diff options
author | David Coppa <dcoppa@cvs.openbsd.org> | 2016-01-02 16:30:56 +0000 |
---|---|---|
committer | David Coppa <dcoppa@cvs.openbsd.org> | 2016-01-02 16:30:56 +0000 |
commit | 41b8c7652dc45b9d8a3cf524e52b337db6627ad0 (patch) | |
tree | fdeda88ef366b036c6367a36cc36daa2ffd306be | |
parent | a6cc7d4dd7688b1e8eb2f8b111f3957638634550 (diff) |
Sync freetype-doc with freetype, i.e. update freetype-doc to
ver. 2.6.2
ok matthieu@
45 files changed, 7949 insertions, 5304 deletions
diff --git a/lib/freetype/docs/css/freetype.css b/lib/freetype/docs/css/freetype.css new file mode 100644 index 000000000..6b5651686 --- /dev/null +++ b/lib/freetype/docs/css/freetype.css @@ -0,0 +1,247 @@ +body { + background-color: #FFFFFF; + background-repeat: no-repeat; + color: #000000; + font-family: verdana, geneva, arial, helvetica, sans-serif; +} +body.top { + background-color: #FFFFFF; + background-repeat: no-repeat; + color: #000000; + padding-top: 250px; + margin-left: 50px; + font-family: verdana, geneva, arial, helvetica, sans-serif; +} +body.z { + background-color: #FFFFFF; + color: #000000; + margin-left: 10%; + margin-right: 10%; + padding: 0; + font-family: verdana, geneva, arial, helvetica, sans-serif; +} +body.front { + background-color: #FFFFFF; + color: #000000; + margin: 0; + padding: 0; + font-family: verdana, geneva, arial, helvetica, sans-serif; +} + +div.version { + margin-bottom: 7ex; +} + +p { + font-size: 10pt; + text-align: justify; +} +p.center { + text-align: center; +} +p.link { + text-align: left; + padding-left: 0.5em; + width: 13.5em; +} +p.label { + text-align: left; + padding-left: 0.5em; + margin-bottom: 1.5ex; + background-color: #06425F; + line-height: 3ex; +} + +h1 { + font-size: 180%; +} +h1.section { + color: #06425F; + font-family: verdana, geneva, arial, helvetica, sans-serif; + font-size: 180%; + margin-top: 2em; +} +h1.zsection { + color: black; + background-color: #CCCCEE; + text-align: center; + font-family: verdana, geneva, arial, helvetica, sans-serif; + font-size: 180%; + padding: 0.3em; + border: none; + width: 100%; +} +h1.intro { + font-size: 24pt; + font-weight: bold; + font-family: sans-serif; + color: #FFFFFF; + text-align: center; + margin-top: 0.3em; + margin-left: 1em; + margin-right: 1em; +} +h2 { + font-size: 150%; +} +h2.section { + color: black; + background-color: #CCCCEE; + text-align: center; + font-family: verdana, geneva, arial, helvetica, sans-serif; + font-size: 120%; + padding: 0.2em; + border: solid; + border-width: 1px; + width: 100%; +} +h3 { + font-size: 120%; +} +h4 { + font-size: 100%; +} + +pre.code { + font-family: "andale mono", lucida, "courier new", courier, monospace; + font-size: small; + color: blue; +} +pre.code i { + font-family: "andale mono", lucida, "courier new", courier, monospace; + font-style: normal; + font-size: small; + color: gray; +} + +table.menu { + border: 0; + border-spacing: 0; + padding: 0; + margin-bottom: 3ex; +} + +tr.menurow { + background-color: #000080; + color: #000000; + vertical-align: middle; +} + +td { + font-family: verdana, geneva, arial, helvetica, sans-serif; + font-size: 10pt; +} +td.menu { + font-family: verdana, geneva, arial, helvetica, sans-serif; + font-size: 10pt; + padding-left: 25px; + padding-right: 25px; + vertical-align: top; +} +td.menucell { + color: #FFFFFF; + background-color: #000080; + font-family: verdana, geneva, arial, helvetica, sans-serif; + font-size: 10pt; +} +td.locationcell { + color: #000000; + background-color: #FFFFFF; + font-family: verdana, geneva, arial, helvetica, sans-serif; + font-size: small; + font-weight: bold; +} +td.titlebar { + color: #000000; + background-color: #C5CAE2; + font-family: verdana, geneva, arial, helvetica, sans-serif; +} + +a:link { + background-color: transparent; + color: #000080; + font-weight: bold; + text-decoration: none; +} +a:visited { + background-color: transparent; + color: #800080; + font-weight: bold; + text-decoration: none; +} +a:active { + background-color: transparent; + color: #FE0000; + font-weight: bold; + text-decoration: none; +} +a:hover { + background-color: transparent; + color: #1919AA; + font-weight: bold; + text-decoration: underline; +} +a.sidebar:link { + background-color: transparent; + color: #000080; + font-weight: normal; + text-decoration: none; +} +a.sidebar:visited { + background-color: transparent; + color: #000080; + font-weight: normal; + text-decoration: none; +} +a.sidebar:active { + background-color: transparent; + color: #FE0000; + font-weight: normal; + text-decoration: none; +} +a.sidebar:hover { + background-color: transparent; + color: #1919AA; + font-weight: normal; + text-decoration: underline; +} +a.menulink { + color: #EEEEEE; + background-color: #000080; + text-decoration: none; + font-family: verdana, geneva, arial, helvetica, sans-serif; + font-size: 10pt; +} +a.menulink:visited { + color: #EEEEEE; + background-color: #000080; + text-decoration: none; +} +a.menulink:hover { + color: #FFFFFF; + background-color: #000080; + text-decoration: none; +} +a.label:link {color: #FFFFFF} +a.label:visited {color: #FFFFFF} +a.label:active {color: #FFFFFF} +a.label:hover {color: #FFFFFF} +a.index:link { + text-decoration: none; + color: #666666 +} +a.index:visited { + text-decoration: none; + color: #666666 +} +a.index:active { + text-decoration: none; + color: #666666 +} +a.index:hover { + text-decoration: underline; + color: #000000 +} + +tt.code { color: gray; } +em.warning { color: red; } diff --git a/lib/freetype/docs/css/freetype2.css b/lib/freetype/docs/css/freetype2.css new file mode 100644 index 000000000..64d755fc5 --- /dev/null +++ b/lib/freetype/docs/css/freetype2.css @@ -0,0 +1,369 @@ +/* freetype2.css */ + +/* the column container layout is based on */ +/* http://matthewjamestaylor.com/blog/perfect-multi-column-liquid-layouts */ + + +/* use Droid fonts */ +@import url("http://fonts.googleapis.com/css?family=Droid+Serif:r,i,b,bi"); +@import url("http://fonts.googleapis.com/css?family=Droid+Sans:r,b"); +@import url("http://fonts.googleapis.com/css?family=Droid+Sans+Mono"); + + +/* top-level appearance */ +body { + width: 100%; + margin: 0em; + padding: 0em; + border: 0em; + text-align: left; + font-size: large; + font-family: "Droid Serif", "serif"; + line-height: 140%; } + +/* table of contents column; */ +/* width and offsets must be synchronized with col2 below */ +#TOC { + background: #F8F8F8; + position: fixed; + font-family: "Droid Sans", "sans-serif"; + font-size: 115%; + left: 0em; + width: 10em; } + +#TOC-bottom { + background: #F8F8F8; + left: 0em; + width: 11.5em; } + +/* don't display list markers in TOC */ +#TOC ul { + list-style: none; + text-align: center; + margin: 0em; + padding: 0em; } +/* separate items with line */ +#TOC ul li { + display: block; + padding-top: 0.5ex; + padding-bottom: 0.5ex; + border-bottom: 1px solid #CCCCCC; } +/* give more vertical spacing for funding icons */ +#TOC ul li.funding { + padding-top: 1ex; + padding-bottom: 1ex; } +#TOC ul li.funding p { + margin-top: 1.5ex; + margin-bottom: 1.5ex; } + +/* this is gray getting black */ +#TOC a:link { + color: #666666; } +#TOC a:visited { + color: #666666; } +#TOC a:active { + color: #666666; } +#TOC a:hover { + color: #000000; } + +/* this is pale red getting red + + #TOC a.emphasis:link { + color: #FF6666; } + #TOC a.emphasis:visited { + color: #FF6666; } + #TOC a.emphasis:active { + color: #FF6666; } + #TOC a.emphasis:hover { + color: #FF0000; } +*/ + +#TOC a.emphasis:link { + color: #666666; } +#TOC a.emphasis:visited { + color: #666666; } +#TOC a.emphasis:active { + color: #666666; } +#TOC a.emphasis:hover { + color: #000000; } + +#TOC a.current:link { + color: #000000; } +#TOC a.current:visited { + color: #000000; } +#TOC a.current:active { + color: #000000; } +#TOC a.current:hover { + color: #000000; } + +/* top bar */ +#top h1 { + position: absolute; + top: 25px; + left: 20px; + margin: 0em; + padding: 0em; + border: 0em; } +.bar { + clear: both; + color: white; + background: #06435E + url("../image/fond3.png") + no-repeat + right + top; + text-align: left; + font-family: "Droid Sans", "sans-serif"; + font-weight: bold; + padding: 0em; + margin: 0em; + border: 0em; + height: 134px; + vertical-align: bottom; } + +#top a { + color: white; + /* pale underline for links */ + text-decoration: none; + border-bottom: 2px solid #16536E; } +#top a:link { + color: white; } +#top a:visited { + color: white; } +#top a:active { + color: white; } +#top a:hover { + color: #CCCCCC; } + +/* column container */ +.colmask { + /* this fixes the IE7 overflow hidden bug */ + /* and stops the layout jumping out of place */ + position: relative; + clear: both; + float: left; + width: 100%; + /* this chops off any overhanging <div>s */ + overflow: hidden; } +/* two-column left menu settings (col1 is right, col2 is left) */ +.leftmenu .colright { + float: left; + width: 200%; + position: relative; + left: 11.5em; /* pad2_l + wd2 + pad2_r */ + background: white; } +.leftmenu .col1wrap { + float: right; + width: 50%; + position: relative; + right: 12em; } /* pad2_l + wd2 + pad2_r */ +.leftmenu .col1 { + margin: 0 1em /* pad2_r */ + 0 12em; /* pad2_l + wd2 + pad2_r + pad1_l */ + position: relative; + right: 100%; + width: 45em; + max-width: 66%; + /* overflow: hidden; */ + padding-left: 2em; } +.leftmenu .col2 { + float: left; + width: 10em; /* wd2 */ + position: relative; + right: 11em; } /* wd2 + pad2_r */ + +/* table of contents */ +#contents ul { + list-style: none; } + +blockquote { + font-style: italic; } + +code { + font-family: "Droid Sans Mono", "monospace"; } + +tt { + font-family: "Droid Sans Mono", "monospace"; } + +pre { + font-family: "Droid Sans Mono", "monospace"; + margin-left: 1.5em; } +pre.example { + color: purple; + font-family: "Droid Sans Mono", "monospace"; + margin-left: 1.5em; } + +span.comment { + color: gray; } +span.important { + font-weight: bold; } + +a { + color: #0000EF; + font-weight: bold; + /* no underline for links */ + text-decoration: none; } +a:link { + color: #000080; } +a:visited { + color: #800080; } +a:active { + color: #FE0000; } +a:hover { + color: #1919AA; } + +h1 { + margin-top: 6ex; } +h2 { + margin-top: 5ex; } +h3 { + margin-top: 4ex; } +h4 { + margin-top: 3ex; } +h5 { } +h6 { } + +h1.title { + text-align: center; } +h1.header { + margin-top: 1ex; + line-height: 200%; } +h2.author { + text-align: center; } +h3.date { + text-align: center; } +h3 + div.date { + margin-top: -3ex; + margin-bottom: 3ex; } +h4 + div.date { + margin-top: -3ex; } + +/* images */ +img.with-border { + padding: 0.5em; } +#TOC img.with-border { + padding: 0.3em; } + +/* figures */ +div.figure { + text-align: center; + margin-top: 5ex; + margin-bottom: 5ex; } +p.caption { + font-size: smaller; } + +/* tables */ +table { + border-collapse: collapse; + /* the next two lines center the table horizontally */ + margin-left: auto; + margin-right: auto; + margin-top: 5ex; + margin-bottom: 5ex; } +td { + padding-left: 0.8em; + padding-right: 0.8em; } +thead { + /* a horizontal rule between table head and body */ + border-bottom: solid thin; } +th { + padding-left: 0.8em; + padding-right: 0.8em; + /* some vertical space before the horizontal rule */ + padding-bottom: 1ex; } +tbody tr:first-child td { + /* some vertical space after the horizontal rule */ + padding-top: 1ex; } + +dl { + margin-left: 1em; } + +dt { + font-weight: bold; } + +/* if we have paragraphs in definition lists, */ +/* suppress the very first vertical space */ +dd > p:first-child { + margin-top: 0ex; } +dd > p { + margin-bottom: 0ex; } + +/* indented text */ +div.quote { + margin-left: 1.5em; } + +/* list for subsections */ +li.tertiary { + font-size: smaller; + text-align: left; + margin-left: 2em; } + +/* list with item headers */ +li.emph p:first-child { + font-weight: bold; } + +ol.algorithm { + font-family: "Droid Sans Mono", "monospace"; } + +/* miscellaneous */ +div.date { + color: #666666; + font-size: smaller; } +div.webmaintainer { + margin-top: 5ex; + font-style: italic; + font-size: 70%; } +div.updated { + margin-top: 5ex; + font-style: italic; + font-size: 70%; } +p.warning { + color: red; } +p.large { + font-size: larger; } +p.note { + font-style: italic; } + +/* +@media screen and (max-width: 40.5em) { + #TOC, + .colmask, + .leftmenu .colright, + .leftmenu .col1wrap, + .leftmenu .col1 { + float: none; + clear: none; + position: relative; + width: 100%; + left: 0em; + right: 100%; + max-width: 100%; + margin: 0em; + padding: 0em; + font-family: "sans-serif"; + } + + #TOC-bottom { + display: none; + } + + #wrapper { + display: table; + line-height: 130%; + padding: 0em 1em; + } + + #TOC { + display: table-header-group; + } + + .colmask { + display: table-footer-group; + } + + #TOC br { + display: none; } +} +*/ + +/* end of file */ diff --git a/lib/freetype/docs/css/freetype2_-30.css b/lib/freetype/docs/css/freetype2_-30.css new file mode 100644 index 000000000..401cdaba3 --- /dev/null +++ b/lib/freetype/docs/css/freetype2_-30.css @@ -0,0 +1,12 @@ +/* freetype2_-30.css */ + +@import "freetype2.css"; + +.bar { + background: #065E4E + url("../image/fond3_-30.png") + no-repeat + right + top; } +#top a { + border-bottom: 2px solid #166E5E; } diff --git a/lib/freetype/docs/css/freetype2_-60.css b/lib/freetype/docs/css/freetype2_-60.css new file mode 100644 index 000000000..d3f44adad --- /dev/null +++ b/lib/freetype/docs/css/freetype2_-60.css @@ -0,0 +1,12 @@ +/* freetype2_-60.css */ + +@import "freetype2.css"; + +.bar { + background: #065E23 + url("../image/fond3_-60.png") + no-repeat + right + top; } +#top a { + border-bottom: 2px solid #166E33; } diff --git a/lib/freetype/docs/css/freetype2_-90.css b/lib/freetype/docs/css/freetype2_-90.css new file mode 100644 index 000000000..86b4a7a72 --- /dev/null +++ b/lib/freetype/docs/css/freetype2_-90.css @@ -0,0 +1,12 @@ +/* freetype2_-90.css */ + +@import "freetype2.css"; + +.bar { + background: #155E06 + url("../image/fond3_-90.png") + no-repeat + right + top; } +#top a { + border-bottom: 2px solid #256E16; } diff --git a/lib/freetype/docs/css/freetype2_30.css b/lib/freetype/docs/css/freetype2_30.css new file mode 100644 index 000000000..28acb435c --- /dev/null +++ b/lib/freetype/docs/css/freetype2_30.css @@ -0,0 +1,12 @@ +/* freetype2_30.css */ + +@import "freetype2.css"; + +.bar { + background: #06175E + url("../image/fond3_30.png") + no-repeat + right + top; } +#top a { + border-bottom: 2px solid #16276E; } diff --git a/lib/freetype/docs/css/freetype2_60.css b/lib/freetype/docs/css/freetype2_60.css new file mode 100644 index 000000000..064ed4c10 --- /dev/null +++ b/lib/freetype/docs/css/freetype2_60.css @@ -0,0 +1,12 @@ +/* freetype2_60.css */ + +@import "freetype2.css"; + +.bar { + background: #21065E + url("../image/fond3_60.png") + no-repeat + right + top; } +#top a { + border-bottom: 2px solid #31166E; } diff --git a/lib/freetype/docs/css/freetype2_90.css b/lib/freetype/docs/css/freetype2_90.css new file mode 100644 index 000000000..af2bc7946 --- /dev/null +++ b/lib/freetype/docs/css/freetype2_90.css @@ -0,0 +1,12 @@ +/* freetype2_90.css */ + +@import "freetype2.css"; + +.bar { + background: #4C065E + url("../image/fond3_90.png") + no-repeat + right + top; } +#top a { + border-bottom: 2px solid #5C166E; } diff --git a/lib/freetype/docs/documentation.html b/lib/freetype/docs/documentation.html new file mode 100644 index 000000000..b7ece3a2f --- /dev/null +++ b/lib/freetype/docs/documentation.html @@ -0,0 +1,185 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> + + <link rel="icon" + href="image/favicon_-60.ico"> + <link rel="shortcut icon" + href="image/favicon_-60.ico"> + <link rel="stylesheet" + type="text/css" + href="css/freetype2_-60.css"> + + <script type="text/javascript" + src="javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="javascript/freetype2.js"> + </script> + + <title>FreeType Documentation</title> +</head> + +<body> + +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> Documentation</h1> +</div> + + +<div id="wrapper"> + +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> + + + <!-- ************************************************** --> + + <div id="introduction"> + <p>Note that the FreeType documentation is also available as + a single archive from + our <a href="http://freetype.org/download.html">download page</a>.</p> + </div> + + + <!-- ************************************************** --> + + <div id="links"> + <h3><a href="glyphs/index.html">FreeType Glyph + Conventions</a></h3> + + <p>This document is a <em>must-read</em> for any user of the + library.</p> + + <h3><a href="ft2faq.html">The FreeType FAQ</a></h3> + + <h3><a href="tutorial/index.html">The FreeType Tutorial</a></h3> + + <h3>The FreeType API Reference</h3> + + <ul> + <li> + <a href="reference/ft2-toc.html">Table Of + Contents</a> + </li> + <li> + <a href="reference/ft2-index.html">Index</a> + </li> + </ul> + + <h3><a href="design/index.html">The Design of + FreeType</a></h3> + + <h3><a href="rasterinfo/rasterinfo.html">The RasterInfo + Font</a></h3> + </div> + + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 05-Oct-2015</p> + </div> + </div> + </div> + + + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="index.html">Overview</a> + </li> + <li class="primary"> + <a href="documentation.html" class="current">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="glyphs/index.html">Glyph Conventions</a> + </li> + <li class="secondary"> + <a href="ft2faq.html">FAQ</a> + </li> + <li class="secondary"> + <a href="tutorial/step1.html">Tutorial</a> + </li> + <li class="secondary"> + <a href="reference/ft2-toc.html">API Reference</a> + </li> + <li class="secondary"> + <a href="design/index.html">Design</a> + </li> + <li class="secondary"> + <a href="rasterinfo/rasterinfo.html">The RasterInfo Font</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> + +<div id="TOC-bottom"> +</div> + +</body> +</html> diff --git a/lib/freetype/docs/ft2faq.html b/lib/freetype/docs/ft2faq.html new file mode 100644 index 000000000..db6d7dcd4 --- /dev/null +++ b/lib/freetype/docs/ft2faq.html @@ -0,0 +1,717 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=US-ASCII"> + <meta name="description" + content="FreeType FAQ"> + <link rel="stylesheet" + href="css/freetype.css"> + <title>FreeType 2 FAQ</title> +</head> + +<body text="#000000" + bgcolor="#FFFFFF" + link="#0000EF" + vlink="#51188E" + alink="#FF0000"> + +<table width="100%" + border="0" + cellspacing="0" + cellpadding="5"> + <tr> + <td bgcolor="#06425F"> + <a href="http://freetype.org/index.html"> + <img src="image/fond3.jpg" + align="right" + border="0" + hspace="0" + vspace="0" + alt="FreeType Homepage"> + </a> + </td> + </tr> + + <tr> + <td bgcolor="#06425F"> + <h1 class="intro">FREETYPE 2 FAQ</h1> + </td> + </tr> + + <tr> + <td bgcolor="#669999"> + <a href="#general" + class="index">General</a> + <a href="#builds" + class="index">Compilation & + Configuration</a> + <a href="#autohint" + class="index">The FreeType 2 + auto-hinter</a> + <a href="#other" + class="index">Other</a> + <font color="#FFFFFF">|</font> + <a href="documentation.html" + class="index">FreeType 2 + documentation</a> + </td> + </tr> +</table> + +<table align="center" + width="80%"> + <tr> + <td> + <h1 class="section">Table of Contents</h1> + + <ul> + <li><a href="#general">General questions</a> + <ul> + <li> + <a href="#general-what">What is FreeType 2?</a> + </li> + <li> + <a href="#general-uses">What can I do with + FreeType 2?</a> + </li> + <li> + <a href="#general-donts">What can I not do with + FreeType 2?</a> + </li> + <li> + <a href="#general-portability">How portable is + FreeType 2?</a> + </li> + <li> + <a href="#general-freetype1">What are the differences between + FreeType 1.x and FreeType 2?</a> + </li> + <li> + <a href="#general-ft1">Is FreeType 2 backwards compatible + to FreeType 1.x?</a> + </li> + <li> + <a href="#general-edit">Can I use FreeType 2 to edit + fonts or create new ones?</a> + </li> + </ul> + </li> + + <li><a href="#builds">Compilation & Configuration</a> + <ul> + <li> + <a href="#builds-compile">How do I compile the FreeType 2 + library?</a> + </li> + <li> + <a href="#builds-config">How do I configure my library + build?</a> + </li> + <li> + <a href="#builds-differences">Why does FreeType render + differently on different platforms?</a> + </li> + </ul> + </li> + + <li> + <a href="#autohint">The FreeType 2 auto-hinter</a> + <ul> + <li> + <a href="#autohint-work">How does the auto-hinter work?</a> + </li> + <li> + <a href="#autohint-other-scripts">Why doesn't the auto-hinter + work well with my script?</a> + </li> + </ul> + </li> + + <li> + <a href="#other">Other questions</a> + <ul> + <li> + <a href="#other-depth">Can I use FreeType to draw text on a + pixmap with arbitrary depth?</a> + </li> + <li> + <a href="#other-color">How can I set the colour of text + rendered by FreeType?</a> + </li> + <li> + <a href="#other-size">I set the pixel size to 8×8, but + the resulting glyphs are larger (or smaller) than that. + Why?</a> + </li> + <li> + <a href="#other-bbox">How can I compute the bounding box of a + text string without loading its glyphs before?</a> + </li> + <li> + <a href="#other-antialias">Which anti-aliasing algorithm is + used by FreeType 2?</a> + </li> + <li> + <a href="#other-opentype">When will FreeType 2 support + OpenType?</a> + </li> + </ul> + </li> + </ul> + + <p><a href="#top" + class="index"> + <img src="image/top.gif" + width="35" + height="19" + align="right" + border="0" + hspace="0" + vspace="0" + alt="Top"></a></p> + + <hr> + + <h1 class="section"> + <a name="general"> + General questions + </a> + </h1> + + <a name="general-what"></a> + <h3> + What is FreeType 2? + </h3> + + <p>It is a software library that can be used by all kinds of + applications to access the contents of font files. Most notably, it + supports the following ‘features’:</p> + + <ul> + <li> + <p>It provides a uniform interface to access font files. It + supports both bitmap and scalable formats, including TrueType, + OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF, and + others.</p> + </li> + + <li> + <p>It supports high-speed anti-aliased glyph bitmap generation + with 256 gray levels.</p> + </li> + + <li> + <p>It is extremely modular, each font format being supported by a + specific module. A build of the library can be tailored to + support only the formats you need, thus reducing code size (a + minimal anti-aliasing build of FreeType can be less than 30KB)</p> + </li> + </ul> + + <hr> + + <a name="general-uses"></a> + <h3> + What can I do with FreeType 2? + </h3> + + <p>FreeType 2 is already used in many products. For example, it + serves as a font rendering engine</p> + + <ul> + <li> + in graphics subsystem and libraries to display text + </li> + <li> + in text layout and pagination services to measure and eventually + render text + </li> + <li> + in font inspection and conversion tools + </li> + </ul> + + <p>Generally speaking, the library allows you to access and manage + the contents of font files in a very easy way.</p> + + <hr> + + <a name="general-donts"></a> + <h3> + What can I not do with FreeType 2? + </h3> + + <p>FreeType 2 doesn't try to perform a number of sophisticated + things, because it focuses on being an excellent <em>font + service</em>.</p> + + <p>This means that the following features are not supported directly + by the library, even though they can be more or less implemented on + top of it, or by using it:</p> + + <ul> + <li> + <p><b>rendering glyphs to arbitrary surfaces</b><br> + FreeType 2 doesn't try to be a graphics library and thus only + supports two pixel formats when rendering glyphs: monochrome 1-bit + bitmaps, or 8-bit gray-level pixmaps.</p> + + <p>If you need to draw glyphs to other kinds of surfaces (for + example, a 24-bit RGB pixmap), you need to use your favorite + graphics library to do just that.</p> + + <p><em>Note however that in the case of rendering scalable glyph + outlines to anti-aliased pixmaps, an application can also provide + its own rendering callback in order to draw or compose directly + the anti-aliased glyph on any target surface.</em></p> + </li> + + <li> + <p><b>glyph caching</b><br> + Each time you request a glyph image from a font, FreeType 2 + does it by parsing the relevant portion of the font file or font + stream and interpreting it according to its font format. This can + be very slow for certain formats, including scalable ones like + TrueType or Type 1.</p> + + <p>Any decent text-rendering sub-system must thus be capable of + caching glyph data in order to reach appropriate rendering + speed.</p> + + <p><em>Note that we provide a caching sub-system with + FreeType 2 since version 2.0.1 which has become quite stable + at the time of this writing (version 2.2.1). However, it might + not suit your needs.</em></p> + </li> + + <li> + <p><b>text layout</b><br> + The library doesn't support text layout operations. Sophisticated + features like glyph substitution, positioning (kerning), + justification, bi-directional ordering, etc.m are not part of a + <em>font service</em> in itself. They must be handled one level + higher.</p> + </li> + </ul> + + <hr> + + <a name="general-portability"></a> + <h3> + How portable is FreeType 2? + </h3> + + <p>The FreeType 2 source code is <em>extremely</em> portable for the + following reasons:</p> + + <ul> + <li> + <p>Everything is written in standard ANSI C.</p> + </li> + <li> + <p>We are very pedantic to avoid any kinds of compiler warnings. + The current source code has been compiled with many compilers + without producing a single warning.</p> + </li> + <li> + <p>The library doesn't use any static writable data at all, making + it an ideal choice on various embedded systems (e.g., it can be + run from ROM directly). It is completely thread-safe too.</p> + </li> + </ul> + + <p>We have made great efforts to ensure that the library is efficient, + compact, and customizable.</p> + + <hr> + + <a name="general-freetype1"></a> + <h3> + What are the differences between FreeType 1.x and + FreeType 2? + </h3> + + <p>The biggest differences are as follows.</p> + + <ul> + <li> + <p>FreeType 1 only supports the TrueType format, while + FreeType 2 supports a lot more.</p> + </li> + + <li> + <p>The FreeType 2 API is simpler as well as more powerful + than the FreeType 1 API.</p> + </li> + + <li> + <p>FreeType 1 includes an extension to support OpenType text + layout processing. This support hasn't become part of + FreeType 2; a much improved version is now part of the <a + href="http://www.pango.org">Pango</a> library.</p> + </li> + </ul> + + <hr> + + <a name="general-ft1"></a> + <h3> + Is FreeType 2 backwards compatible with FreeType 1.x? + </h3> + + <p>Short answer: No. However, transition from 1.x to 2 should be + rather straightforward.</p> + + <p>The FreeType 2 API is a lot simpler than the one in 1.x + while being much more powerful. We thus encourage you to adapt your + source code to it as this should not involve much work.</p> + + <hr> + + <a name="general-edit"></a> + <h3> + Can I use FreeType 2 to edit fonts or create new ones? + </h3> + + <p>No. The library has been specifically designed to <em>read</em> + font files with small code size and very low memory usage.</p> + + <p>A good, freely available font editor is <a + href="http://fontforge.org/">FontForge</a>.</p> + + <p><a href="#top" + class="index"> + <img src="image/top.gif" + width="35" + height="19" + align="right" + border="0" + hspace="0" + vspace="0" + alt="Top"></a></p> + + <hr> + + <h1 class="section"> + <a name="builds"> + Compilation & Configuration + </a> + </h1> + + <a name="builds-compile"></a> + <h3> + How do I compile the FreeType 2 library? + </h3> + + <p>The library can be compiled in various ways, and detailed + documentation is available in documentation directory of the + FreeType 2 source tree.</p> + + <p>For compilation on the command line, GNU make is necessary; other + build tools won't work. The source bundle also comes with project + files for some graphical IDEs like Visual C; note, however, that those + files are sometimes not up to date since it is contributed code not + used by the core developers.</p> + + <hr> + + <a name="builds-config"></a> + <h3> + How do I configure my build of the library? + </h3> + + <p>This is fully described in the file <tt>CUSTOMIZATION</tt> in + FreeType's documentation directory. Basically, you have to edit the + header file <tt>ftoption.h</tt> for compile-time options and to select + the modules with the file <tt>modules.cfg</tt>. Finally, it is + possible to replace the standard system interface (dealing with memory + allocation and stream I/O) with a custom one.</p> + + <hr> + + <a name="builds-differences"></a> + <h3> + Why does FreeType render differently on different platforms? + </h3> + + <p>Different distributions compile FreeType with different options. + The developer version of a distribution's FreeType package, which is + needed to compile your program against FreeType, includes the file + <tt>ftoption.h</tt>. Compare each platform's copy of + <tt>ftoption.h</tt> to find the differences.</p> + + <p><a href="#top" + class="index"> + <img src="image/top.gif" + width="35" + height="19" + align="right" + border="0" + hspace="0" + vspace="0" + alt="Top"></a></p> + + <hr> + + <h1 class="section"> + <a name="autohint"> + The FreeType 2 auto-hinter + </a> + </h1> + + <a name="autohint-work"></a> + <h3> + How does the auto-hinter work? + </h3> + + <p><em>Please note that the name of auto-hinter module is + <b>autofit</b>, which is a reimplementation of the old autohint + module.</em></p> + + <p>A rather complete description of the hinting algorithm (which is + slightly out of date regarding the internal structures) can be found + in the TUG-boat article <a + href="http://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf">Real-Time + Grid Fitting of Typographic Outlines</a>.</p> + + <p>The auto-hinter performs grid-fitting on scalable font formats that + use Bézier outlines as their primary glyph image format (this + means nearly all scalable font formats today). If a given font driver + doesn't provide its own hinter, the auto-hinter is used by default. + If a format-specific hinter is provided, it is still possible to use + the auto-hinter using the <tt>FT_LOAD_FORCE_AUTOHINT</tt> bit flag + when calling <tt>FT_Load_Glyph()</tt>.</p> + + <p>Currently, the auto-hinter doesn't use external hints to do its + job, as it automatically computes global metrics (when it + ‘opens’ a font for the first time) and glyph + ‘hints’ from their outline. + + <hr> + + <a name="autohint-other-scripts"></a> + <h3> + Why doesn't the auto-hinter work well with my script? + </h3> + + <p>The auto-hinter was first designed to manage and hint Latin-based + fonts, as they consist of most of the fonts available today. It now + supports Asian fonts, but not other complex scripts like Arabic.</p> + + <p>Hinting various scripts isn't really more difficult than Latin, + just different, with a set of different constraints, which must be + hard-coded into the autofit module. Volunteers welcome!</p> + + <p><a href="#top" + class="index"> + <img src="image/top.gif" + width="35" + height="19" + align="right" + border="0" + hspace="0" + vspace="0" + alt="Top"></a></p> + + <hr> + + <h1 class="section"> + <a name="other"> + Other questions + </a> + </h1> + + <a name="other-depth"></a> + <h3> + Can I use FreeType to draw text on a pixmap with arbitrary depth? + </h3> + + <p>Not directly, as FreeType is a font library, not a general-purpose + graphics library or text rendering service. However, note that the + anti-aliased renderer allows you to convert a vectorial glyph outline + into a list of ‘spans’ (i.e., horizontal pixel segments + with the same coverage) that can be rendered through user-provided + callbacks.</p> + + <p>By providing the appropriate span callback, you can render + anti-aliased text to any kind of surface. You can also use any + colour, fill pattern or fill image if you want to. This process is + called <em>direct rendering</em>.</p> + + <p>A complete example is given at the end of the <a + href="tutorial/step3.html">FreeType 2 tutorial</a>. + + <p>Note that direct rendering is <em>not</em> available with + monochrome output, as the current renderer uses a two-pass algorithm + to generate glyphs with correct drop-out control.</p> + + <hr> + + <a name="other-color"></a> + <h3> + How can I set the colour of text rendered by FreeType? + </h3> + + <p>Basically, you can't do that, because FreeType is simply a font + library. In general, you need to use your favorite graphics library + to draw the FreeType glyphs with the appropriate colour.</p> + + <p>Note that for anti-aliased glyphs, you can ‘set the + colour’ by using <em>direct rendering</em> as described in <a + href="#other-depth">this answer</a>.</p> + + <hr> + + <a name="other-size"></a> + <h3> + I set the pixel size to 8×8, but the resulting glyphs are + larger (or smaller) than that. Why? + </h3> + + <p>A lot of people have difficulties to understand this topic, because + they think of glyphs as fixed-width or fixed-height + ‘cells’, like those of fonts used in terminals/consoles. + This assumption is not valid with most ‘modern’ font + formats, even for bitmapped-based ones like <b>PCF</b> or + <b>BDF</b>.</p> + + <p>Be aware that the <em>character size</em> that is set either + through <tt>FT_Set_Char_Size()</tt> or <tt>FT_Set_Pixel_Sizes()</tt> + isn't directly related to the dimension of the generated glyph + bitmaps!</p> + + <p>Rather, the character size is indeed the size of <em>an abstract + square</em>, called the <em>EM</em>, used by typographers to design + fonts. Scaling two distinct fonts to the same character size, be it + expressed in points or pixels, generally results in bitmaps with + <em>distinct dimensions</em>!</p> + + <p>Note that historically, the EM corresponded to the width of a + capital ‘M’ in Latin typefaces. However, later + improvements in typography led to designs that greatly deviate from + this rule. Today, it is not possible to connect the EM size to a + specific font ‘feature’ in a reliable way.</p> + + <hr> + + <a name="other-bbox"></a> + <h3> + How can I compute the bounding box of a text string without loading + its glyphs before? + </h3> + + <p>This is not possible in general. Reason is that hinting distorts + the glyph shape for optimal rasterization, and this process sometimes + creates outlines which have considerably different metrics. The + TrueType format provides the (optional) ‘hdmx’ table which + contains device horizontal metrics for selected pixel sizes, but even + here the vertical metrics are missing.</p> + + <p>It is probably best to use both a glyph and a metrics cache to + avoid recomputation.</p> + + <hr> + + <a name="other-antialias"></a> + <h3> + Which anti-aliasing algorithm is used by FreeType 2? + </h3> + + <p>The algorithm has been specifically designed for FreeType. It is + based on ideas that were originally found in the implementation of the + <a href="http://www.levien.com/libart/">libArt</a> graphics library to + compute the <em>exact pixel coverage</em> of a vector image with no + sub-sampling and filtering.</p> + + <p>However, these two implementations are radically distinct and use + vastly different models. The FreeType 2 renderer is optimized + specifically for rendering small complex shapes, like glyphs, at very + high speed while using very few memory. On the other hand, libArt has + been designed for general shape and polygon processing, especially + large ones.</p> + + <p>The FreeType 2 anti-aliasing renderer is indeed + <em>faster</em> than the monochrome renderer for small character sizes + (typically <20 pixels). The reason is that the monochrome + renderer must perform two passes on the outline in order to perform + drop-out control according to the TrueType specification.</p> + + <hr> + + <a name="other-opentype"></a> + <h3> + When will FreeType 2 support OpenType? + </h3> + + <p>Well, the engine already reads OpenType/CFF files perfectly. What + it doesn't do is handling ‘OpenType Layout’ tables.</p> + + <p>FreeType 1 comes with a set of extensions that are used to + load and manage OpenType Layout tables. It even has a demonstration + program named <tt>ftstrtto</tt> to show its capabilities. However, + this code is no longer maintained, and we strongly advise to not use + it.</p> + + <p>For FreeType 2, we have decided that the layout operations + provided through these tables are better placed in a specific + text-layout library like <a href="http://www.pango.org">Pango</a>.</p> + + <p><a href="#top" + class="index"> + <img src="image/top.gif" + width="35" + height="19" + align="right" + border="0" + hspace="0" + vspace="0" + alt="Top"></a></p> + </td> + </tr> + </table> + +<font size=-3>Last update: 25-Feb-2011</font> + +<table width="100%" + border="0" + cellspacing="0" + cellpadding="5"> + <tr> + <td bgcolor="#669999"> + <a href="#general" + class="index">General</a> + <a href="#builds" + class="index">Compilation & + Configuration</a> + <a href="#autohint" + class="index">The FreeType 2 + auto-hinter</a> + <a href="#other" + class="index">Other</a> + <font color="#FFFFFF">|</font> + <a href="documentation.html" + class="index">FreeType + documentation</a> + </td> + </tr> + + <tr> + <td bgcolor="#06425F"> + <a href="http://freetype.org/index.html"> + <img src="image/fond3.jpg" + align="right" + border="0" + hspace="0" + vspace="0" + alt="FreeType Homepage"> + </a> + </td> + </tr> +</table> + +</body> +</html> diff --git a/lib/freetype/docs/glyphs/glyphs-1.html b/lib/freetype/docs/glyphs/glyphs-1.html index e9d781027..ccee2699a 100644 --- a/lib/freetype/docs/glyphs/glyphs-1.html +++ b/lib/freetype/docs/glyphs/glyphs-1.html @@ -1,200 +1,271 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en" - "http://www.w3.org/TR/REC-html40/loose.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + <head> <meta http-equiv="Content-Type" - content="text/html; charset=iso-8859-1"> + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> <meta name="Author" content="David Turner"> - <title>FreeType Glyph Conventions</title> + + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + + <title>FreeType Glyph Conventions / I</title> </head> -<body text="#000000" - bgcolor="#FFFFFF" - link="#0000EF" - vlink="#51188E" - alink="#FF0000"> - -<h1 align=center> - FreeType Glyph Conventions -</h1> - -<h2 align=center> - Version 2.1 -</h2> - -<h3 align=center> - Copyright 1998-2000 David Turner (<a - href="mailto:david@freetype.org">david@freetype.org</a>)<br> - Copyright 2000 The FreeType Development Team (<a - href="mailto:devel@freetype.org">devel@freetype.org</a>) -</h3> - -<center> -<table width="65%"> -<tr><td> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-2.html">Next</a> - </td> - </tr> - </table> - </center> - - <p><hr></p> - - <table width="100%"> - <tr bgcolor="#CCCCFF" - valign=center><td> - <h2> - I. Basic typographic concepts - </h2> - </td></tr> - </table> - - <a name="section-1"> - <h3> - 1. Font files, format and information - </h3> - - <p>A font is a collection of various character images that can be used - to display or print text. The images in a single font share some common - properties, including look, style, serifs, etc. Typographically - speaking, one has to distinguish between a <em>font family</em> and its - multiple <em>font faces</em>, which usually differ in style though come - from the same template.</p> - - For example, "Palatino Regular" and "Palatino Italic" are two distinct - <em>faces</em> from the same famous <em>family</em>, called "Palatino" - itself.</p> - - <p>The single term <em>font</em> is nearly always used in ambiguous ways - to refer to either a given family or given face, depending on the - context. For example, most users of word-processors use "font" to - describe a font family (e.g. "Courier", "Palatino", etc.); however most - of these families are implemented through several data files depending - on the file format: For TrueType, this is usually one per face (i.e. - <tt>arial.ttf</tt> for "Arial Regular", <tt>ariali.ttf</tt> for "Arial - Italic", etc.). The file is also called a "font" but really contains a - font face.</p> - - <p>A <em>digital font</em> is thus a data file that may contain <em>one - or more font faces</em>. For each of these, it contains character - images, character metrics, as well as other kind of information - important to the layout of text and the processing of specific character - encodings. In some awkward formats, like Adobe's Type 1, a single - font face is described through several files (i.e. one contains the - character images, another one the character metrics). We will ignore - this implementation issue in most parts of this document and consider - digital fonts as single files, though FreeType 2.0 is able to - support multiple-files fonts correctly.</p> - - <p>As a convenience, a font file containing more than one face is called - a <em>font collection</em>. This case is rather rare but can be seen in - many Asian fonts, which contain images for two or more representation - forms of a given scripts (usually for horizontal and vertical - layout.</p> - - - <a name="section-2"> - <h3> - 2. Character images and mappings - </h3> - - <p>The character images are called <em>glyphs</em>. A single character - can have several distinct images, i.e. several glyphs, depending on - script, usage or context. Several characters can also take a single - glyph (good examples are Roman ligatures like "fi" and "fl" which can be - represented by a single glyph). The relationships between characters - and glyphs can be very complex, but won't be discussed in this document. - Moreover, some formats use more or less awkward schemes to store and - access glyphs. For the sake of clarity, we only retain the following - notions when working with FreeType:</p> - - <ul> - <li> - <p>A font file contains a set of glyphs; each one can be stored as a - bitmap, a vector representation or any other scheme (most scalable - formats use a combination of mathematical representation and control - data/programs). These glyphs can be stored in any order in the font - file, and is typically accessed through a simple glyph index.</p> - </li> - <li> - <p>The font file contains one or more tables, called a <em>character - map</em> (or charmap in short), which is used to convert character - codes for a given encoding (e.g. ASCII, Unicode, DBCS, Big5, etc..) - into glyph indices relative to the font file. A single font face - may contain several charmaps. For example, most TrueType fonts - contain an Apple-specific charmap as well as a Unicode charmap, - which makes them usable on both Mac and Windows platforms.</p> - </li> - </ul> - - - <a name="section-3"> - <h3> - 3. Character and font metrics - </h3> - - <p>Each glyph image is associated with various metrics which are used to - describe how must be placed and managed when rendering text. These - are described in more details in section III, they relate to - glyph placement, cursor advances as well as text layout. They are - extremely important to compute the flow of text when rendering a string - of text.</p> - - <p>Each scalable format also contains some global metrics, expressed in - notional units, to describe some properties of all glyphs in the same - face. Examples for global metrics are the maximum glyph bounding box, - the ascender, descender and text height for the font.</p> - - <p>Though these metrics also exist for non-scalable formats, they only - apply for a set of given character dimensions and resolutions, and - are usually expressed in pixels then.</p> - - - <p><hr></p> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" valign=center> - <td align=center - width="30%"> - - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-2.html">Next</a> - </td> - </tr> - </table> - </center> - -</td></tr> -</table> -</center> + +<body> + +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> Glyph + Conventions / I</h1> +</div> + + +<div id="wrapper"> + +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> + + + <!-- ************************************************** --> + + <div id="basic-typographic-concepts"> + <h2>I. Basic Typographic Concepts</h2> + + <h3 id="section-1">1. Font files, format and + information</h3> + + <p>A <em>font</em> is a collection of various character + images that can be used to display or print text. The + images in a single font share some common properties, + including look, style, serifs, etc. Typographically + speaking, one has to distinguish between a <em>font + family</em> and its multiple <em>font faces</em>, which + usually differ in style though come from the same + template.</p> + + <p>For example, ‘Palatino Regular’ and + ‘Palatino Italic’ are two distinct + <em>faces</em> from the same <em>family</em>, called + ‘Palatino’ itself.</p> + + <p>The single term ‘font’ is nearly always used + in ambiguous ways to refer to either a given family or + given face, depending on the context. For example, most + users of word-processors use ‘font’ to + describe a font family (e.g. ‘Courier’, + ‘Palatino’, etc.); however, most of these + families are implemented through several data files + depending on the file format: For TrueType, this is + usually one per face (i.e. <tt>arial.ttf</tt> for + ‘Arial Regular’, <tt>ariali.ttf</tt> for + ‘Arial Italic’, etc.). The file is also + called a ‘font’ but really contains a font + face.</p> + + <p>A <em>digital font</em> is thus a data file that may + contain <em>one or more font faces</em>. For each of + these, it contains character images, character metrics, as + well as other kind of information important to the layout + of text and the processing of specific character + encodings. In some formats, like Adobe's Type 1, a + single font face is described through several files (i.e., + one contains the character images, another one the + character metrics). We will ignore this implementation + issue in most parts of this document and consider digital + fonts as single files, though FreeType 2 is able to + support multiple-files fonts correctly.</p> + + <p>As a convenience, a font file containing more than one + face is called a <em>font collection</em>. This case is + rather rare but can be seen in many Asian fonts, which + contain images for two or more representation forms of a + given scripts (usually for horizontal and vertical + layout.</p> + + + <h3 id="section-2">2. Character images and + mappings</h3> + + <p>The character images are called <em>glyphs</em>. A + single character can have several distinct images, + i.e. several glyphs, depending on script, usage or + context. Several characters can also take a single glyph + (good examples are Roman ligatures like ‘fi’ + and ‘fl’ which can be represented by a single + glyph). The relationship between characters and glyphs + can be very complex but won't be discussed in this + document. Moreover, some formats use more or less + complicated schemes to store and access glyphs. For the + sake of clarity, we only retain the following notions when + working with FreeType:</p> + + <ul> + <li> + <p>A font file contains a set of glyphs; each one can be + stored as a bitmap, a vector representation, or any + other scheme (most scalable formats use a combination + of mathematical representation and control + data/programs). These glyphs can be stored in any + order in the font file, and are typically accessed + through a simple glyph index.</p> + </li> + <li> + <p>The font file contains one or more tables, called + <em>character maps</em> (also called + ‘charmaps’ or ‘cmaps’ for + short), which are used to convert character codes for + a given encoding (e.g. ASCII, Unicode, DBCS, Big5, + etc.) into glyph indices relative to the font file. A + single font face may contain several charmaps. For + example, many TrueType fonts contain an Apple-specific + charmap as well as a Unicode charmap, which makes them + usable on both Mac and Windows platforms.</p> + </li> + </ul> + + + <h3 id="section-3">3. Character and font metrics</h3> + + <p>Each glyph image is associated with various metrics which + describe how to place and manage it when rendering text; + see <a href="glyphs-3.html">section III</a> for more. + Metrics relate to glyph placement, cursor advances as well + as text layout. They are extremely important to compute + the flow of text when rendering a string of text.</p> + + <p>Each scalable format also contains some global metrics, + expressed in notional (i.e. font) units, to describe some + properties of all glyphs in the same face. Examples for + global metrics are the maximum glyph bounding box, the + ascender, descender, and text height of the font.</p> + + <p>Non-scalable formats contain metrics also. However, they + only apply to a set of given character dimensions and + resolutions, and are usually expressed in pixels then.</p> + </div> + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 07-Dec-2014</p> + </div> + </div> + </div> + + + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="index.html">FreeType Glyph Conventions</a> + </li> + <li class="tertiary"> + <a href="glyphs-1.html" class="current">Basic Typographic Concepts</a> + </li> + <li class="tertiary"> + <a href="glyphs-2.html">Glyph Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-3.html">Glyph Metrics</a> + </li> + <li class="tertiary"> + <a href="glyphs-4.html">Kerning</a> + </li> + <li class="tertiary"> + <a href="glyphs-5.html">Text Processing</a> + </li> + <li class="tertiary"> + <a href="glyphs-6.html">FreeType Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-7.html">FreeType Bitmaps</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> + +<div id="TOC-bottom"> +</div> </body> </html> - diff --git a/lib/freetype/docs/glyphs/glyphs-2.html b/lib/freetype/docs/glyphs/glyphs-2.html index 9d99ba01a..60ff4c508 100644 --- a/lib/freetype/docs/glyphs/glyphs-2.html +++ b/lib/freetype/docs/glyphs/glyphs-2.html @@ -1,395 +1,472 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en" - "http://www.w3.org/TR/REC-html40/loose.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + <head> <meta http-equiv="Content-Type" - content="text/html; charset=iso-8859-1"> + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> <meta name="Author" content="David Turner"> - <title>FreeType Glyph Conventions</title> + + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + + <title>FreeType Glyph Conventions / II</title> </head> -<body text="#000000" - bgcolor="#FFFFFF" - link="#0000EF" - vlink="#51188E" - alink="#FF0000"> - -<h1 align=center> - FreeType Glyph Conventions -</h1> - -<h2 align=center> - Version 2.1 -</h2> - -<h3 align=center> - Copyright 1998-2000 David Turner (<a - href="mailto:david@freetype.org">david@freetype.org</a>)<br> - Copyright 2000, 2007 The FreeType Development Team (<a - href="mailto:devel@freetype.org">devel@freetype.org</a>) -</h3> - -<center> -<table width="65%"> -<tr><td> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-1.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-3.html">Next</a> - </td> - </tr> - </table> - </center> - - <p><hr></p> - - <table width="100%"> - <tr bgcolor="#CCCCFF" - valign=center><td> - <h2> - II. Glyph Outlines - </h2> - </td></tr> - </table> - - <p>This section describes the way scalable representations of glyph images, - called outlines, are used by FreeType as well as client applications.</p> - - <a name="section-1"> - <h3> - 1. Pixels, points and device resolutions - </h3> - - <p>Though it is a very common assumption when dealing with computer - graphics programs, the physical dimensions of a given pixel (be it for - screens or printers) are not squared. Often, the output device, be it a - screen or printer, exhibits varying resolutions in both horizontal and - vertical direction, and this must be taken care of when rendering - text.</p> - - <p>It is thus common to define a device's characteristics through two - numbers expressed in <em>dpi</em> (dots per inch). For example, a - printer with a resolution of 300x600 dpi has 300 pixels per - inch in the horizontal direction, and 600 in the vertical one. The - resolution of a typical computer monitor varies with its size - (15" and 17" monitors don't have the same pixel sizes at - 640x480), and of course the graphics mode resolution.</p> - - <p>As a consequence, the size of text is usually given in - <em>points</em>, rather than device-specific pixels. Points are a - simple <em>physical</em> unit, where 1 point = 1/72th of - an inch, in digital typography. As an example, most Roman books are - printed with a body text whose size is somewhere between 10 and - 14 points.</p> - - <p>It is thus possible to compute the size of text in pixels from the - size in points with the following formula:</p> - - <center> - <tt>pixel_size = point_size * resolution / 72</tt> - </center> - - <p>The resolution is expressed in <em>dpi</em>. Since horizontal and - vertical resolutions may differ, a single point size usually defines a - different text width and height in pixels.</p> - - <p><em>Unlike what is often thought, the "size of text in pixels" is not - directly related to the real dimensions of characters when they are - displayed or printed. The relationship between these two concepts is a - bit more complex and relate to some design choices made by the font - designer. This is described in more detail in the next sub-section (see - the explanations on the EM square).</em></p> - - - <a name="section-2"> - <h3> - 2. Vectorial representation - </h3> - - <p>The source format of outlines is a collection of closed paths called - <em>contours</em>. Each contour delimits an outer or inner - <em>region</em> of the glyph, and can be made of either <em>line - segments</em> or <em>Bézier arcs</em>.</p> - - <p>The arcs are defined through <em>control points</em>, and can be - either second-order (these are <em>conic</em> Béziers) or - third-order (<em>cubic</em> Béziers) polynomials, depending on - the font format. Note that conic Béziers are usually called - <em>quadratic</em> Béziers in the literature. Hence, each point - of the outline has an associated flag indicating its type (normal or - control point). And scaling the points will scale the whole - outline.</p> - - <p>Each glyph's original outline points are located on a grid of - indivisible units. The points are usually stored in a font file as - 16-bit integer grid coordinates, with the grid origin's being at (0,0); - they thus range from -16384 to 16383. (Even though point - coordinates can be floats in other formats such as Type 1, we will - restrict our analysis to integer values for simplicity).</p> - - <p><em>The grid is always oriented like the traditional mathematical - two-dimensional plane, i.e., the <i>X</i> axis from the left to the - right, and the <i>Y</i> axis from bottom to top.</em></p> - - <p>In creating the glyph outlines, a type designer uses an imaginary - square called the <em>EM square</em>. Typically, the EM square can be - thought of as a tablet on which the characters are drawn. The square's - size, i.e., the number of grid units on its sides, is very important for - two reasons:</p> - - <ul> - <li> - <p>It is the reference used to scale the outlines to a given text - dimension. For example, a size of 12pt at 300x300 dpi - corresponds to 12*300/72 = 50 pixels. This is the - size the EM square would appear on the output device if it was - rendered directly. In other words, scaling from grid units to - pixels uses the formula:</p> - - <p><center> - <tt>pixel_size = point_size * resolution / 72</tt><br> - <tt>pixel_coord = grid_coord * pixel_size / EM_size</tt> - </center></p> - </li> - <li> - <p>The greater the EM size is, the larger resolution the designer - can use when digitizing outlines. For example, in the extreme - example of an EM size of 4 units, there are only 25 point - positions available within the EM square which is clearly not - enough. Typical TrueType fonts use an EM size of 2048 units; - Type 1 PostScript fonts have a fixed EM size of 1000 grid - units but point coordinates can be expressed as floating values.</p> - </li> - </ul> - - <p>Note that glyphs can freely extend beyond the EM square if the font - designer wants so. The EM is used as a convenience, and is a valuable - convenience from traditional typography.</p> - - <p>Grid units are very often called <em>font units</em> or <em>EM - units</em>.</p> - - <p><em>As said before, <tt>pixel_size</tt> computed in the above formula - does not relate directly to the size of characters on the screen. It - simply is the size of the EM square if it was to be displayed. Each - font designer is free to place its glyphs as it pleases him within the - square. This explains why the letters of the following text have not - the same height, even though they are displayed at the same point size - with distinct fonts:</em> - - <p><center> - <img src="body_comparison.png" - height=40 width=580 - alt="Comparison of font heights"> - </center></p> - - <p>As one can see, the glyphs of the Courier family are smaller than - those of Times New Roman, which themselves are slightly smaller than - those of Arial, even though everything is displayed or printed at a size - of 16 points. This only reflects design choices.</p> - - - <a name="section-3"> - <h3> - 3. Hinting and Bitmap rendering - </h3> - - <p>The outline as stored in a font file is called the "master" outline, - as its points coordinates are expressed in font units. Before it can be - converted into a bitmap, it must be scaled to a given size/resolution. - This is done through a very simple transformation, but always creates - undesirable artifacts, e.g. stems of different widths or heights in - letters like "E" or "H".</p> - - <p>As a consequence, proper glyph rendering needs the scaled points to - be aligned along the target device pixel grid, through an operation - called <em>grid-fitting</em> (often called <em>hinting</em>). One of its - main purposes is to ensure that important widths and heights are - respected throughout the whole font (for example, it is very often - desirable that the "I" and the "T" have their central vertical line of - the same pixel width), as well as to manage features like stems and - overshoots, which can cause problems at small pixel sizes.</p> - - <p>There are several ways to perform grid-fitting properly; most - scalable formats associate some control data or programs with each glyph - outline. Here is an overview:</p> - - <ul> - <li> - <p><em>explicit grid-fitting</em></p> - - <p>The TrueType format defines a stack-based virtual machine, for - which programs can be written with the help of more than - 200 opcodes (most of these relating to geometrical operations). - Each glyph is thus made of both an outline and a control program to - perform the actual grid-fitting in the way defined by the font - designer.</p> - </li> - <li> - <p><em>implicit grid-fitting (also called hinting)</em></p> - - <p>The Type 1 format takes a much simpler approach: Each glyph - is made of an outline as well as several pieces called - <em>hints</em> which are used to describe some important features of - the glyph, like the presence of stems, some width regularities, and - the like. There aren't a lot of hint types, and it is up to the - final renderer to interpret the hints in order to produce a fitted - outline.</p> - </li> - <li> - <p><em>automatic grid-fitting</em></p> - - <p>Some formats simply include no control information with each - glyph outline, apart font metrics like the advance width and height. It - is then up to the renderer to "guess" the more interesting features - of the outline in order to perform some decent grid-fitting.</p> - </li> - </ul> - - <p>The following table summarises the pros and cons of each scheme.</p> - - <center> - <table width="90%" - bgcolor="#CCCCCC" - cellpadding=5> - <tr bgcolor="#999999"> - <td> - <center> - <b>grid-fitting scheme</b> - </center> - </td> - <td> - <center> - <b>advantages</b> - </center> - </td> - <td> - <center> - <b>disadvantages</b> - </center> - </td> - </tr> - <tr> - <td valign=top> - <center> - <b>explicit</b> - </center> - </td> +<body> - <td valign=top> - <p><b>Quality.</b> Excellent results at small sizes are possible. - This is very important for screen display.</p> +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> Glyph + Conventions / II</h1> +</div> - <p><b>Consistency.</b> All renderers produce the same glyph - bitmaps.</p> - </td> - <td valign=top> - <p><b>Speed.</b> Interpreting bytecode can be slow if the glyph - programs are complex.</p> +<div id="wrapper"> - <p><b>Size.</b> Glyph programs can be long.</p> +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> - <p><b>Technical difficulty.</b> - It is extremely difficult to write good hinting - programs. Very few tools available.</p> - </td> - </tr> - <tr> - <td valign=top> - <center> - <b>implicit</b> - </center> - </td> - <td valign=top> - <p><b>Size.</b> Hints are usually much smaller than explicit glyph - programs.</p> + <!-- ************************************************** --> + + <div id="glyph-outlines"> + <h2>II. Glyph Outlines</h2> - <p><b>Speed.</b> - Grid-fitting is usually a fast process.</p> - </td> + <p>This section describes the way scalable representations + of glyph images, called outlines, are used by FreeType as + well as client applications.</p> - <td valign=top> - <p><b>Quality.</b> Often questionable at small sizes. Better with - anti-aliasing though.</p> + <h3 id="section-1">1. Pixels, points and device + resolutions</h3> - <p><b>Inconsistency.</b> Results can vary between different - renderers, or even distinct versions of the same engine.</p> - </td> - </tr> + <p>Though it is a very common assumption when dealing with + computer graphics programs, the physical dimensions of a + given pixel (be it for screens or printers) are not + squared. Often, the output device, be it a screen device + or a printer, exhibits varying resolutions in both + horizontal and vertical directions, and this must be taken + care of when rendering text.</p> + + <p>It is thus common to define a device's characteristics + through two numbers expressed in <em>dpi</em> (dots per + inch). For example, a printer with a resolution of + 300×600 dpi has 300 pixels per inch in the + horizontal direction, and 600 in the vertical one. The + resolution of a typical computer monitor varies with its + size (10″ and 25″ monitors don't + have the same pixel sizes at 1024×768), and of + course the graphics mode resolution.</p> + + <p>As a consequence, the size of text is usually given in + <em>points</em>, rather than device-specific pixels. + Points are a <em>physical</em> unit, where 1 point + equals 1/72th of an inch in digital typography. As an + example, most books using the Latin script are printed + with a body text size somewhere between 10 and + 14 points.</p> + + <p>It is thus possible to compute the size of text in pixels + from the size in points with the following formula:</p> - <tr> - <td valign=top> <center> - <b>automatic</b> + <tt>pixel_size = point_size * resolution / 72</tt> </center> - </td> - - <td valign=top> - <p><b>Size.</b> No need for control information, resulting in - smaller font files.</p> - - <p><b>Speed.</b> Depends on the grid-fitting algorithm. Usually - faster than explicit grid-fitting.</p> - </td> - - <td valign=top> - <p><b>Quality.</b> Often questionable at small sizes. Better with - anti-aliasing though.</p> - - <p><b>Speed.</b> Depends on the grid-fitting algorithm.</p> - - <p><b>Inconsistency.</b> Results can vary between different - renderers, or even distinct versions of the same engine.</p> - </td> - </tr> - </table> - </center> - - <p><hr></p> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-1.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-3.html">Next</a> - </td> - </tr> - </table> - </center> - -</td></tr> -</table> -</center> + + <p>The resolution is expressed in <em>dpi</em>. Since + horizontal and vertical resolutions may differ, a single + point size usually defines a different text width and + height in pixels.</p> + + <p><em>Unlike what is often thought, the ‘size of text + in pixels’ is not directly related to the real + dimensions of characters when they are displayed or + printed. The relationship between these two concepts is + a bit more complex and depend on some design choices + made by the font designer. This is described in more + detail in the next sub-section (see the explanations on + the EM square).</em></p> + + + <h3 id="section-2">2. Vectorial representation</h3> + + <p>The source format of outlines is a collection of closed paths called + <em>contours</em>. Each contour delimits an outer or + inner <em>region</em> of the glyph, and can be made of + either <em>line segments</em> or <em>Bézier + arcs</em>.</p> + + <p>The arcs are defined through <em>control points</em>, and + can be either second-order (these are <em>conic</em> + Béziers) or third-order (<em>cubic</em> + Béziers) polynomials, depending on the font format. + Note that conic Béziers are usually called + <em>quadratic</em> Béziers in the literature. + Hence, FreeType associates each point of the outline with + flag to indicate its type (normal or control point). And + scaling the points will scale the whole outline.</p> + + <p>Each glyph's original outline points are located on a + grid of indivisible units. The points are usually stored + in a font file as 16-bit integer grid coordinates, with + the grid's origin being at (0,0); they thus range from + -32768 to 32767. (Even though point coordinates can + be floats in other formats such as Type 1, we will + restrict our analysis to integer values for + simplicity).</p> + + <p><em>The grid is always oriented like the traditional + mathematical two-dimensional plane, i.e., + the <i>X</i> axis goes from the left to the right, + and the <i>Y</i> axis from bottom to top.</em></p> + + <p>In creating the glyph outlines, a type designer uses an + imaginary square called the <em>EM square</em>. + Typically, the EM square can be thought of as a tablet on + which the characters are drawn. The square's size, i.e., + the number of grid units on its sides, is very important + for two reasons:</p> + + <ul> + <li> + <p>It is the reference size used to scale the outlines + to a given text dimension. For example, a size of + 12pt at 300×300 dpi corresponds to + 12*300/72 = 50 pixels. This is the + size the EM square would appear on the output device + if it was rendered directly. In other words, scaling + from grid units to pixels uses the formula:</p> + + <p align="center"> + <tt>pixel_size = point_size * resolution / 72</tt><br> + <tt>pixel_coord = grid_coord * pixel_size / EM_size</tt> + </p> + </li> + <li> + <p>The greater the EM size is, the larger resolution the + designer can use when digitizing outlines. For + example, in the extreme example of an EM size of + 4 units, there are only 25 point positions + available within the EM square which is clearly not + enough. Typical TrueType fonts use an EM size of + 2048 units; Type 1 or CFF PostScript fonts + traditionally use an EM size of 1000 grid units + (but point coordinates can be expressed as floating + values).</p> + </li> + </ul> + + <p>Note that glyphs can freely extend beyond the EM square + if the font designer wants so. The EM square is thus just + a convention in traditional typography.</p> + + <p>Grid units are very often called <em>font units</em> + or <em>EM units</em>.</p> + + <p><em>As said before, <tt>pixel_size</tt> computed in the + above formula does not directly relate to the size of + characters on the screen. It simply is the size of the + EM square if it was to be displayed. Each font designer + is free to place its glyphs as it pleases him within the + square. This explains why the letters of the following + text have not the same height, even though they are + displayed at the same point size with distinct + fonts:</em></p> + + <p align="center"> + <img src="body_comparison.png" + height="40" + width="580" + alt="Comparison of font heights"> + </p> + + <p>As one can see, the glyphs of the Courier family are + smaller than those of Times New Roman, which themselves + are slightly smaller than those of Arial, even though + everything is displayed or printed at a size of + 16 points. This only reflects design choices.</p> + + + <h3 id="section-3">3. Hinting and Bitmap rendering</h3> + + <p>The outline as stored in a font file is called the + ‘master’ outline, as its points coordinates + are expressed in font units. Before it can be converted + into a bitmap, it must be scaled to a given size and + resolution. This is done with a very simple + transformation, but always creates undesirable artifacts, + in particular stems of different widths or heights in + letters like ‘E’ or ‘H’.</p> + + <p>As a consequence, proper glyph rendering needs the scaled + points to be aligned along the target device pixel grid, + through an operation called <em>grid-fitting</em> (often + called <em>hinting</em>). One of its main purposes is to + ensure that important widths and heights are respected + throughout the whole font (for example, it is very often + desirable that the ‘I’ and the ‘T’ + have their central vertical line of the same pixel width), + as well as to manage features like stems and overshoots, + which can cause problems at small pixel sizes.</p> + + <p>There are several ways to perform grid-fitting properly; + most scalable formats associate some control data or + programs with each glyph outline. Here is an + overview:</p> + + <ul> + <li class="emph"> + <p>explicit grid-fitting</p> + + <p>The TrueType format defines a stack-based virtual + machine, for which programs can be written with the + help of more than 200 opcodes (most of them + relating to geometrical operations). Each glyph is + thus made of both an outline and a control program to + perform the actual grid-fitting in the way defined by + the font designer.</p> + </li> + <li class="emph"> + <p>implicit grid-fitting (also called hinting)</p> + + <p>The Type 1 and CFF formats take a much simpler + approach: Each glyph is made of an outline as well as + several pieces called <em>hints</em> which are used to + describe some important features of the glyph, like + the presence of stems, some width regularities, and + the like. There aren't a lot of hint types, and it is + up to the final renderer to interpret the hints in + order to produce a fitted outline.</p> + </li> + <li class="emph"> + <p>automatic grid-fitting</p> + + <p>Some formats include no control information with each + glyph outline, apart from font metrics like the + advance width and height. It is then up to the + renderer to ‘guess’ the more interesting + features of the outline in order to perform some + decent grid-fitting.</p> + </li> + </ul> + + <p>The following table summarizes the pros and cons of each + scheme.</p> + + <table> + <thead> + <tr> + <th align="center"> + <b>grid-fitting scheme</b> + </th> + <th align="center"> + <b>advantages</b> + </th> + <th align="center"> + <b>disadvantages</b> + </th> + </tr> + </thead> + + <tbody> + <tr> + <td valign="top" align="center"> + <p><b>explicit</b></p> + </td> + + <td valign="top"> + <p><b>Quality.</b> Excellent results at small sizes + are possible. This is very important for screen + display.</p> + + <p><b>Consistency.</b> All renderers produce the + same glyph bitmaps (at least in theory).</p> + </td> + + <td valign="top"> + <p><b>Speed.</b> Interpreting bytecode can be slow + if the glyph programs are complex.</p> + + <p><b>Size.</b> Glyph programs can be long.</p> + + <p><b>Technical difficulty.</b> It is extremely + difficult to write good hinting programs. Very + few tools available.</p> + </td> + </tr> + <tr> + <td valign="top" align="center"> + <p><b>implicit</b></p> + </td> + + <td valign="top"> + <p><b>Size.</b> Hints are usually much smaller than + explicit glyph programs.</p> + + <p><b>Speed.</b> Grid-fitting is usually a fast + process.</p> + </td> + + <td valign="top"> + <p><b>Quality.</b> Often questionable at small + sizes. Better with anti-aliasing though.</p> + + <p><b>Inconsistency.</b> Results can vary between + different renderers, or even distinct versions of + the same engine.</p> + </td> + </tr> + + <tr> + <td valign="top" align="center"> + <p><b>automatic</b></p> + </td> + + <td valign="top"> + <p><b>Size.</b> No need for control information, + resulting in smaller font files.</p> + + <p><b>Speed.</b> Depends on the grid-fitting + algorithm. Usually faster than explicit + grid-fitting.</p> + </td> + + <td valign="top"> + <p><b>Quality.</b> Often questionable at small + sizes. Better with anti-aliasing though.</p> + + <p><b>Speed.</b> Depends on the grid-fitting + algorithm.</p> + + <p><b>Inconsistency.</b> Results can vary between + different renderers, or even distinct versions + of the same engine.</p> + </td> + </tr> + </tbody> + </table> + </div> + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 07-Dec-2014</p> + </div> + </div> + </div> + + + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="index.html">FreeType Glyph Conventions</a> + </li> + <li class="tertiary"> + <a href="glyphs-1.html">Basic Typographic Concepts</a> + </li> + <li class="tertiary"> + <a href="glyphs-2.html" class="current">Glyph Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-3.html">Glyph Metrics</a> + </li> + <li class="tertiary"> + <a href="glyphs-4.html">Kerning</a> + </li> + <li class="tertiary"> + <a href="glyphs-5.html">Text Processing</a> + </li> + <li class="tertiary"> + <a href="glyphs-6.html">FreeType Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-7.html">FreeType Bitmaps</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> + +<div id="TOC-bottom"> +</div> </body> </html> diff --git a/lib/freetype/docs/glyphs/glyphs-3.html b/lib/freetype/docs/glyphs/glyphs-3.html index 32f367ea0..7793f1b27 100644 --- a/lib/freetype/docs/glyphs/glyphs-3.html +++ b/lib/freetype/docs/glyphs/glyphs-3.html @@ -1,430 +1,519 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en" - "http://www.w3.org/TR/REC-html40/loose.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + <head> <meta http-equiv="Content-Type" - content="text/html; charset=iso-8859-1"> + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> <meta name="Author" content="David Turner"> - <title>FreeType Glyph Conventions</title> + + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + + <title>FreeType Glyph Conventions / III</title> </head> -<body text="#000000" - bgcolor="#FFFFFF" - link="#0000EF" - vlink="#51188E" - alink="#FF0000"> - -<h1 align=center> - FreeType Glyph Conventions -</h1> - -<h2 align=center> - Version 2.1 -</h2> - -<h3 align=center> - Copyright 1998-2000 David Turner (<a - href="mailto:david@freetype.org">david@freetype.org</a>)<br> - Copyright 2000 The FreeType Development Team (<a - href="mailto:devel@freetype.org">devel@freetype.org</a>) -</h3> - -<center> -<table width="65%"> -<tr><td> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-2.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-4.html">Next</a> - </td> - </tr> - </table> - </center> - - <p><hr></p> - - <table width="100%"> - <tr bgcolor="#CCCCFF" - valign=center><td> - <h2> - III. Glyph metrics - </h2> - </td></tr> - </table> - - <a name="section-1"> - <h3> - 1. Baseline, pens and layouts - </h3> - - <p>The baseline is an imaginary line that is used to "guide" glyphs when - rendering text. It can be horizontal (e.g. Roman, Cyrillic, Arabic, - etc.) or vertical (e.g. Chinese, Japanese, Korean, etc). Moreover, to - render text, a virtual point, located on the baseline, called the <em>pen - position</em> or <em>origin</em>, is used to locate glyphs.</p> - - <p>Each layout uses a different convention for glyph placement:</p> - - <ul> - <li> - <p>With horizontal layout, glyphs simply "rest" on the baseline. - Text is rendered by incrementing the pen position, either to the - right or to the left.</p> - - <p>The distance between two successive pen positions is - glyph-specific and is called the <em>advance width</em>. Note that - its value is <em>always</em> positive, even for right-to-left - oriented alphabets, like Arabic. This introduces some differences - in the way text is rendered.</p> - - <p><em>The pen position is always placed on the baseline.</em></p> - - <p><center> - <img src="Image1.png" - height=179 width=458 - alt="horizontal layout"> - </center></p> - </li> - <li> - <p>With a vertical layout, glyphs are centered around the - baseline:</p> - - <p><center> - <img src="Image2.png" - height=275 width=162 - alt="vertical layout"> - </center></p> - </li> - </ul> - - - <a name="section-2"> - <h3> - 2. Typographic metrics and bounding boxes - </h3> - - <p>A various number of face metrics are defined for all glyphs in a - given font.</p> - - <ul> - <li> - <p><em>Ascent</em></p> - - <p>The distance from the baseline to the highest/upper grid - coordinate used to place an outline point. It is a positive value, - due to the grid's orientation with the <i>Y</i> axis - upwards.</p> - </li> - - <li> - <p><em>Descent</em></p> - - <p>The distance from the baseline to the lowest grid coordinate used - to place an outline point. This is a negative value, due to the - grid's orientation.</p> - </li> - - <li> - <p><em>Linegap</em></p> - - <p>The distance that must be placed between two lines of text. The - baseline-to-baseline distance should be computed as: - - <center><p> - <tt>ascent - descent + linegap</tt> - </p></center> - - <p>if you use the typographic values.</p> - </li> - </ul> - - <p>Other, simpler metrics are:</p> - - <ul> - <li> - <p><em>The glyph's bounding box</em>, also called <em>bbox</em></p> - - <p>This is an imaginary box that encloses all glyphs from the font, - usually as tightly as possible. It is represented by four fields, - namely <tt>xMin</tt>, <tt>yMin</tt>, <tt>xMax</tt>, and - <tt>yMax</tt>, that can be computed for any outline. Their values - can be in font units (if measured in the original outline) or in - fractional/integer pixel units (when measured on scaled - outlines).</p> - - <p>Note that if it wasn't for grid-fitting, you wouldn't need to - know a box's complete values, but only its dimensions to know how - big is a glyph outline/bitmap. However, correct rendering of hinted - glyphs needs the preservation of important grid alignment on each - glyph translation/placement on the baseline.</p> - </li> - - <li> - <p><em>Internal leading</em></p> - - <p>This concept comes directly from the world of traditional - typography. It represents the amount of space within the - <em>leading</em> which is reserved for glyph features that lay - outside of the EM square (like accentuation). It usually can be - computed as:</p> - - <center><p> - <tt>internal leading = ascent - descent - EM_size</tt> - </p></center> - </li> - - <li> - <p><em>External leading</em></p> - - <p>This is another name for the line gap.</p> - </li> - </ul> - - - <a name="section-3"> - <h3> - 3. Bearings and Advances - </h3> - - Each glyph has also distances called <em>bearings</em> and - <em>advances</em>. Their definition is constant, but their values - depend on the layout, as the same glyph can be used to render text - either horizontally or vertically: - - <ul> - <li> - <p><em>Left side bearing</em> or <em>bearingX</em></p> - - <p>The horizontal distance from the current pen position to the - glyph's left bbox edge. It is positive for horizontal layouts, and - in most cases negative for vertical ones.</p> - </li> - - <li> - <p><em>Top side bearing</em> or <em>bearingY</em></p> - - <p>The vertical distance from the baseline to the top of the glyph's - bbox. It is usually positive for horizontal layouts, and negative - for vertical ones.</p> - </li> - - <li> - <p><em>Advance width</em> or <em>advanceX</em></p> - - <p>The horizontal distance the pen position must be incremented (for - left-to-right writing) or decremented (for right-to-left writing) by - after each glyph is rendered when processing text. It is always - positive for horizontal layouts, and null for vertical ones.</p> - </li> - - <li> - <p><em>Advance height</em> <em>advanceY</em></p> - - <p>The vertical distance the pen position must be decremented by - after each glyph is rendered. It is always null for horizontal - layouts, and positive for vertical layouts.</p> - </li> - - <li> - <p><em>Glyph width</em></p> - - <p>The glyph's horizontal extent. For unscaled font coordinates, it - is <tt>bbox.xMax-bbox.xMin</tt>. For scaled glyphs, its computation - requests specific care, described in the grid-fitting chapter - below.</p> - </li> - - <li> - <p><em>Glyph height</em> - - <p>The glyph's vertical extent. For unscaled font coordinates, it is - <tt>bbox.yMax-bbox.yMin</tt>. For scaled glyphs, its computation - requests specific care, described in the grid-fitting chapter - below.</p> - </li> - - <li> - <p><em>Right side bearing</em></p> - - <p>Only used for horizontal layouts to describe the distance from - the bbox's right edge to the advance width. It is in most cases a - non-negative number:</p> - - <p><center> - <tt>advance_width - left_side_bearing - (xMax-xMin)</tt> - </center></p> - </li> - </ul> - - <p>Here is a picture giving all the details for horizontal metrics: - - <center><p> - <img src="Image3.png" - height=253 width=388 - alt="horizontal glyph metrics"> - </p></center> - - <p>And here is another one for the vertical metrics:</p> - - <center><p> - <img src="Image4.png" - height=278 width=294 - alt="vertical glyph metrics"> - </p></center> - - - <a name="section-4"> - <h3> - 4. The effects of grid-fitting - </h3> - - <p>Because hinting aligns the glyph's control points to the pixel grid, - this process slightly modifies the dimensions of character images in - ways that differ from simple scaling.</p> - - <p>For example, the image of the lowercase "m" letter sometimes fits a - square in the master grid. However, to make it readable at small pixel - sizes, hinting tends to enlarge its scaled outline in order to keep its - three legs distinctly visible, resulting in a larger character - bitmap.</p> - - <p>The glyph metrics are also influenced by the grid-fitting process: - - <ul> - <li> - The image's width and height are altered. Even if this is only by - one pixel, it can make a big difference at small pixel sizes. - </li> - <li> - The image's bounding box is modified, thus modifying the bearings. - </li> - <li> - The advances must be updated. For example, the advance width must - be incremented if the hinted bitmap is larger than the scaled one, - to reflect the augmented glyph width. - </li> - </ul> - - <p>This has some implications:</p> - - <ul> - <li> - Because of hinting, simply scaling the font ascent or descent might - not give correct results. A possible solution is to keep the ceiling - of the scaled ascent, and floor of the scaled descent. - </li> - - <li> - There is no easy way to get the hinted glyph and advance widths of a - range of glyphs, as hinting works differently on each outline. The - only solution is to hint each glyph separately and record the - returned values. Some formats, like TrueType, even include a table - of pre-computed values for a small set of common character pixel - sizes. - </li> - <li> - Hinting depends on the final character width and height in pixels, - which means that it is highly resolution-dependent. This property - makes correct WYSIWYG layouts difficult to implement. - </li> - </ul> - - - <em> - <p>Performing 2D transformations on glyph outlines is very easy with - FreeType. However, when using translation on a hinted outlines, one - should aways take care of <b>exclusively using integer pixel - distances</b> (which means that the parameters to the - <tt>FT_Outline_Translate()</tt> API should all be multiples - of 64, as the point coordinates are in 26.6 fixed-point - format).</p> - - <p>Otherwise, the translation will simply <em>ruin the hinter's - work</em>, resulting in a very low quality bitmaps!</p> - </em> - - - <a name="section-5"> - <h3> - 5. Text widths and bounding box - </h3> - - <p>As seen before, the "origin" of a given glyph corresponds to the - position of the pen on the baseline. It is not necessarily located on - one of the glyph's bounding box corners, unlike many typical bitmapped - font formats. In some cases, the origin can be out of the bounding box, - in others, it can be within it, depending on the shape of the given - glyph.</p> - - <p>Likewise, the glyph's "advance width" is the increment to apply to - the pen position during layout, and is not related to the glyph's - "width", which really is the glyph's bounding width. - - <p>The same conventions apply to strings of text. This means that: - - <ul> - <li> - The bounding box of a given string of text doesn't necessarily - contain the text cursor, nor is the latter located on one of its - corners. - </li> - - <li> - The string's advance width isn't related to its bounding box - dimensions. Especially if it contains beginning and terminal spaces - or tabs. - </li> - <li> - Finally, additional processing like kerning creates strings of text - whose dimensions are not directly related to the simple - juxtaposition of individual glyph metrics. For example, the advance - width of "VA" isn't the sum of the advances of "V" and "A" taken - separately. - </li> - </ul> - - <p><hr></p> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-2.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-4.html">Next</a> - </td> - </tr> - </table> - </center> - -</td></tr> -</table> -</center> + +<body> + +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> Glyph + Conventions / III</h1> +</div> + + +<div id="wrapper"> + +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> + + + <!-- ************************************************** --> + + <div id="glyph-metrics"> + <h2>III. Glyph Metrics</h2> + + <h3 id="section-1">1. Baseline, pens and layouts</h3> + + <p>The baseline is an imaginary line that is used to + ‘guide’ glyphs when rendering text. It can be + horizontal (e.g. Latin, Cyrillic, Arabic, etc.) or + vertical (e.g. Chinese, Japanese, Mongolian, etc.). + Moreover, to render text, a virtual point, located on the + baseline, called the <em>pen position</em> + or <em>origin</em>, is used to locate glyphs.</p> + + <p>Each layout uses a different convention for glyph + placement:</p> + + <ul> + <li> + <p>With horizontal layout, glyphs simply + ‘rest’ on the baseline. Text is rendered + by incrementing the pen position, either to the right + or to the left.</p> + + <p>The distance between two successive pen positions is + glyph-specific and is called the <em>advance + width</em>. Note that its value is <em>always</em> + positive, even for right-to-left oriented scripts like + Arabic. This introduces some differences in the way + text is rendered.</p> + + <p><em>The pen position is always placed on the + baseline.</em></p> + + <p align="center"> + <img src="Image1.png" + height="179" + width="458" + alt="horizontal layout"> + </p> + </li> + <li> + <p>With a vertical layout, glyphs are centered around + the baseline:</p> + + <p align="center"> + <img src="Image2.png" + height="275" + width="162" + alt="vertical layout"> + </p> + </li> + </ul> + + + <h3 id="section-2">2. Typographic metrics and bounding + boxes</h3> + + <p>A various number of face metrics are defined for all + glyphs in a given font.</p> + + <ul> + <li class="emph"> + <p>Ascent</p> + + <p>The distance from the baseline to the highest or + upper grid coordinate used to place an outline point. + It is a positive value, due to the grid's orientation + with the <i>Y</i> axis upwards.</p> + </li> + <li class="emph"> + <p>Descent</p> + + <p>The distance from the baseline to the lowest grid + coordinate used to place an outline point. In + FreeType, this is a negative value, due to the grid's + orientation. Note that in some font formats this is a + positive value.</p> + </li> + <li class="emph"> + <p>Linegap</p> + + <p>The distance that must be placed between two lines of + text. The baseline-to-baseline distance should be + computed as + + <p align="center"> + <tt>linespace = ascent - descent + linegap</tt> + </p> + + <p>if you use the typographic values.</p> + </li> + </ul> + + <p>Other, simpler metrics are:</p> + + <ul> + <li class="emph"> + <p>Bounding box</p> + + <p>This is an imaginary box that encloses all glyphs + from the font, usually as tightly as possible. It is + represented by four parameters, + namely <tt>xMin</tt>, <tt>yMin</tt>, <tt>xMax</tt>, + and <tt>yMax</tt>, that can be computed for any + outline. Their values can be in font units if + measured in the original outline, or in integer (or + fractional) pixel units when measured on scaled + outlines.</p> + + <p>A common shorthand for the bounding box is + ‘bbox’.</p> + </li> + <li class="emph"> + <p>Internal leading</p> + + <p>This concept comes directly from the world of traditional + typography. It represents the amount of space within the + <em>leading</em> which is reserved for glyph features + that lay outside of the EM square (like accentuation). + It usually can be computed as</p> + + <p align="center"> + <tt>internal leading = ascent - descent - EM_size</tt> + </p> + </li> + <li class="emph"> + <p>External leading</p> + + <p>This is another name for the line gap.</p> + </li> + </ul> + + + <h3 id="section-3">3. Bearings and Advances</h3> + + <p>Each glyph has also distances called <em>bearings</em> and + <em>advances</em>. The actual values depend on the + layout, as the same glyph can be used to render text + either horizontally or vertically:</p> + + <ul> + <li class="emph"> + <p>Left side bearing</p> + + <p>The horizontal distance from the current pen position + to the glyph's left bbox edge. It is positive for + horizontal layouts, and in most cases negative for + vertical ones.</p> + + <p>In the FreeType API, this is also called + <tt>bearingX</tt>. Another shorthand is + ‘lsb’.</p> + </li> + <li class="emph"> + <p>Top side bearing</p> + + <p>The vertical distance from the baseline to the top of + the glyph's bbox. It is usually positive for + horizontal layouts, and negative for vertical + ones.</p> + + <p>In the FreeType API, this is also called + <tt>bearingY</tt>.</p> + </li> + <li class="emph"> + <p>Advance width</p> + + <p>The horizontal distance to increment (for + left-to-right writing) or decrement (for right-to-left + writing) the pen position after a glyph has been + rendered when processing text. It is always positive + for horizontal layouts, and zero for vertical + ones.</p> + + <p>In the FreeType API, this is also called + <tt>advanceX</tt>.</p> + </li> + <li class="emph"> + <p>Advance height</p> + + <p>The vertical distance to decrement the pen position + after a glyph has been rendered. It is always zero + for horizontal layouts, and positive for vertical + layouts.</p> + + <p>In the FreeType API, this is also called + <tt>advanceY</tt>.</p> + </li> + <li class="emph"> + <p>Glyph width</p> + + <p>The glyph's horizontal extent. For unscaled font + coordinates, it is</p> + + <p align="center"> + <tt>glyph width = bbox.xMax - bbox.xMin</tt> + </p> + + <p>For scaled glyphs, its computation requests specific + care, described in the grid-fitting chapter below.</p> + </li> + <li class="emph"> + <p>Glyph height</p> + + <p>The glyph's vertical extent. For unscaled font + coordinates, it is</p> + + <p align="center"> + <tt>glyph height = bbox.yMax - bbox.yMin</tt> + </p> + + <p>For scaled glyphs, its computation requests specific + care, described in the grid-fitting chapter below.</p> + </li> + <li class="emph"> + <p>Right side bearing</p> + + <p>Only used for horizontal layouts to describe the + distance from the bbox's right edge to the advance + width. In most cases it is a non-negative number:</p> + + <p align="center"> + <tt>right side bearing = advance_width - + left_side_bearing - (xMax-xMin)</tt> + </p> + + <p>A common shorthand for this value is + ‘rsb’.</p> + </li> + </ul> + + <p>Here is a picture giving all the details for horizontal metrics: + + <p align="center"> + <img src="Image3.png" + height="253" + width="388" + alt="horizontal glyph metrics"> + </p> + + <p>And here is another one for the vertical metrics:</p> + + <p align="center"> + <img src="Image4.png" + height="278" + width="294" + alt="vertical glyph metrics"> + </p> + + + <h3 id="section-4">4. The effects of grid-fitting</h3> + + <p>Because hinting aligns the glyph's control points to the + pixel grid, this process slightly modifies the dimensions + of character images in ways that differ from simple + scaling.</p> + + <p>For example, the image of the lowercase ‘m’ + letter sometimes fits a square in the master grid. + However, to make it readable at small pixel sizes, hinting + tends to enlarge its scaled outline horizontally in order + to keep its three legs distinctly visible, resulting in a + wider character bitmap.</p> + + <p>The glyph metrics are also influenced by the grid-fitting + process:</p> + + <ul> + <li> + <p>The image's width and height are altered. Even if + this is only by one pixel, it can make a big + difference at small pixel sizes.</p> + </li> + <li> + <p>The image's bounding box is modified, thus modifying + the bearings.</p> + </li> + <li> + <p>The advances must be updated. For example, the + advance width must be incremented if the hinted bitmap + is larger than the scaled one, to reflect the + augmented glyph width.</p> + </li> + </ul> + + <p>This has some implications:</p> + + <ul> + <li> + <p>Because of hinting, simply scaling the font ascent or + descent might not give correct results. A possible + solution is to keep the ceiling of the scaled ascent, + and floor of the scaled descent.</p> + </li> + <li> + <p>There is no easy way to get the hinted glyph and + advance widths of a range of glyphs, as hinting works + differently on each outline. The only solution is to + hint each glyph separately and record the returned + values (for example in a cache). Some formats, like + TrueType, even include a table of pre-computed values + for a small set of common character pixel sizes.</p> + </li> + <li> + <p>Hinting depends on the final character width and + height in pixels, which means that it is highly + resolution-dependent. This property makes correct + WYSIWYG layouts difficult to implement.</p> + </li> + </ul> + + <p>Performing 2D transformations on glyph outlines is very + easy with FreeType. However, when using translation on + hinted outlines, one should always take care + of <b>exclusively using integer pixel distances</b> (which + means that the parameters to the + <tt>FT_Outline_Translate</tt> API function should all be + multiples of 64, as the point coordinates are in + 26.6 fixed-point format). Otherwise, the translation + will simply <em>ruin the hinter's work</em>, resulting in + very low quality bitmaps!</p> + + + <h3 id="section-5">5. Text widths and bounding box</h3> + + <p>As seen before, the ‘origin’ of a given glyph + corresponds to the position of the pen on the baseline. + It is not necessarily located on one of the glyph's + bounding box corners, unlike many typical bitmapped font + formats. In some cases, the origin can be out of the + bounding box, in others, it can be within it, depending on + the shape of the given glyph.</p> + + <p>Likewise, the glyph's ‘advance width’ is the + increment to apply to the pen position during layout, and + is not related to the glyph's ‘width’, which + really is the glyph's bounding width.</p> + + <p>The same conventions apply to strings of text. This + means that:</p> + + <ul> + <li> + <p>The bounding box of a given string of text doesn't + necessarily contain the text cursor, nor is the latter + located on one of its corners.</p> + </li> + <li> + <p>The string's advance width isn't related to its + bounding box dimensions. Especially if it contains + beginning and terminal spaces or tabs.</p> + </li> + <li> + <p>Finally, additional processing like kerning creates + strings of text whose dimensions are not directly + related to the simple juxtaposition of individual + glyph metrics. For example, the advance width of + ‘VA’ isn't the sum of the advances of + ‘V’ and ‘A’ taken + separately.</p> + </li> + </ul> + </div> + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 07-Dec-2014</p> + </div> + </div> + </div> + + + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="index.html">FreeType Glyph Conventions</a> + </li> + <li class="tertiary"> + <a href="glyphs-1.html">Basic Typographic Concepts</a> + </li> + <li class="tertiary"> + <a href="glyphs-2.html">Glyph Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-3.html" class="current">Glyph Metrics</a> + </li> + <li class="tertiary"> + <a href="glyphs-4.html">Kerning</a> + </li> + <li class="tertiary"> + <a href="glyphs-5.html">Text Processing</a> + </li> + <li class="tertiary"> + <a href="glyphs-6.html">FreeType Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-7.html">FreeType Bitmaps</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> + +<div id="TOC-bottom"> +</div> </body> </html> diff --git a/lib/freetype/docs/glyphs/glyphs-4.html b/lib/freetype/docs/glyphs/glyphs-4.html index 669ce63da..70e0bda08 100644 --- a/lib/freetype/docs/glyphs/glyphs-4.html +++ b/lib/freetype/docs/glyphs/glyphs-4.html @@ -1,231 +1,284 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en" - "http://www.w3.org/TR/REC-html40/loose.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + <head> <meta http-equiv="Content-Type" - content="text/html; charset=iso-8859-1"> + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> <meta name="Author" content="David Turner"> - <title>FreeType Glyph Conventions</title> + + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + + <title>FreeType Glyph Conventions / IV</title> </head> -<body text="#000000" - bgcolor="#FFFFFF" - link="#0000EF" - vlink="#51188E" - alink="#FF0000"> - -<h1 align=center> - FreeType Glyph Conventions -</h1> - -<h2 align=center> - Version 2.1 -</h2> - -<h3 align=center> - Copyright 1998-2000 David Turner (<a - href="mailto:david@freetype.org">david@freetype.org</a>)<br> - Copyright 2000 The FreeType Development Team (<a - href="mailto:devel@freetype.org">devel@freetype.org</a>) -</h3> - -<center> -<table width="65%"> -<tr><td> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-3.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-5.html">Next</a> - </td> - </tr> - </table> - </center> - - <p><hr></p> - - <table width="100%"> - <tr bgcolor="#CCCCFF" - valign=center><td> - <h2> - IV. Kerning - </h2> - </td></tr> - </table> - - <p>The term <em>kerning</em> refers to specific information used to - adjust the relative positions of coincident glyphs in a string of text. - This section describes several types of kerning information, as well as - the way to process them when performing text layout.</p> - - - <a name="section-1"> - <h3> - 1. Kerning pairs - </h3> - - <p>Kerning consists of modifying the spacing between two successive - glyphs according to their outlines. For example, a "T" and a "y" can be - easily moved closer, as the top of the "y" fits nicely under the upper - right bar of the "T".</p> - - <p>When laying out text with only their standard widths, some - consecutive glyphs seem a bit too close or too distant. For example, - the space between the "A" and the "V" in the following word seems a - little wider than needed.</p> - - <center><p> - <img src="bravo_unkerned.png" - height=37 width=116 - alt="the word 'bravo' unkerned"> - </p></center> - - <p>Compare this to the same word, where the distance between these two - letters has been slightly reduced:</p> - - <center><p> - <img src="bravo_kerned.png" - height=37 width=107 - alt="the word 'bravo' with kerning"> - </p></center> - - <p>As you can see, this adjustment can make a great difference. Some - font faces thus include a table containing kerning distances for a set - of given glyph pairs for text layout.</p> - - <ul> - <li> - <p>The pairs are ordered, i.e., the space for pair (A,V) isn't - necessarily the space for pair (V,A). They also index glyphs, and - not characters.</p> - </li> - <li> - <p>Kerning distances can be expressed in horizontal or vertical - directions, depending on layout and/or script. For example, some - horizontal layouts like Arabic can make use of vertical kerning - adjustments between successive glyphs. A vertical script can have - vertical kerning distances.</p> - </li> - <li> - <p>Kerning distances are expressed in grid units. They are usually - oriented in the <i>X</i> axis, which means that a negative - value indicates that two glyphs must be set closer in a horizontal - layout.</p> - </li> - </ul> - - - <a name="section-2"> - <h3> - 2. Applying kerning - </h3> - - <p>Applying kerning when rendering text is a rather easy process. It - merely consists in adding the scaled kern distance to the pen position - before writing each next glyph. However, the typographically correct - renderer must take a few more details in consideration.</p> - - <p>The "sliding dot" problem is a good example: Many font faces include - a kerning distance between capital letters like "T" or "F" and a - following dot ("."), in order to slide the latter glyph just right to - their main leg:</p> - - <center><p> - <img src="twlewis1.png" - height=38 width=314 - alt="example for sliding dots"> - </p></center> - - <p>This sometimes requires additional adjustments between the dot and - the letter following it, depending on the shapes of the enclosing - letters. When applying "standard" kerning adjustments, the previous - sentence would become:</p> - - <center><p> - <img src="twlewis2.png" - height=36 width=115 - alt="example for too much kerning"> - </p></center> - - <p>This is clearly too contracted. The solution here, as exhibited in - the first example, is to only slide the dots when possible. Of course, - this requires a certain knowledge of the text's meaning. The above - adjustments would not necessarily be welcome if we were rendering the - final dot of a given paragraph.</p. - - <p>This is only one example, and there are many others showing that a - real typographer is needed to layout text properly. If not available, - some kind of user interaction or tagging of the text could be used to - specify some adjustments, but in all cases, this requires some support - in applications and text libraries.</p> - - <p>For more mundane and common uses, however, we can have a very simple - algorithm, which avoids the sliding dot problem, and others, though not - producing optimal results. It can be seen as</p> - - <ol> - <li> - Place the first glyph on the baseline. - </li> - <li> - Save the location of the pen position/origin in <tt>pen1</tt>. - </li> - <li> - Adjust the pen position with the kerning distance between the first - and second glyph. - </li> - <li> - Place the second glyph and compute the next pen position/origin in - <tt>pen2</tt>. - </li> - <li> - Use <tt>pen1</tt> as the next pen position if it is beyond - <tt>pen2</tt>, use <tt>pen2</tt> otherwise. - </li> - </ol> - - - <p><hr></p> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-3.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-5.html">Next</a> - </td> - </tr> - </table> - </center> - -</td></tr> -</table> -</center> + +<body> + +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> Glyph + Conventions / IV</h1> +</div> + + +<div id="wrapper"> + +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> + + + <!-- ************************************************** --> + + <div id="kerning"> + <h2>IV. Kerning</h2> + + <p>The term <em>kerning</em> refers to specific information + used to adjust the relative positions of successive glyphs + in a string of text. This section describes several types + of kerning information, as well as the way to process them + when performing text layout.</p> + + + <h3 id="section-1">1. Kerning pairs</h3> + + <p>Kerning consists of modifying the spacing between two + successive glyphs according to their outlines. For + example, a ‘T’ and a ‘y’ can be + easily moved closer, as the top of the ‘y’ + fits nicely under the upper right bar of the + ‘T’.</p> + + <p>When laying out text with only their standard widths, + some consecutive glyphs seem a bit too close or too + distant. For example, the space between the + ‘A’ and the ‘V’ in the following + word seems a little wider than needed.</p> + + <p align="center"> + <img src="bravo_unkerned.png" + height="37" + width="116" + alt="the word 'bravo' unkerned"> + </p> + + <p>Compare this to the same word, where the distance between + these two letters has been slightly reduced:</p> + + <p align="center"> + <img src="bravo_kerned.png" + height="37" + width="107" + alt="the word 'bravo' with kerning"> + </p> + + <p>As you can see, this adjustment can make a great + difference. Some font faces thus include a table + containing kerning distances for a set of given glyph + pairs for text layout.</p> + + <ul> + <li> + <p>The pairs are ordered, i.e., the space for pair + ‘(A,V)’ isn't necessarily the space for + pair ‘(V,A)’. They also use glyph + indices, not character codes.</p> + </li> + <li> + <p>Kerning distances can be expressed in horizontal or + vertical directions, depending on the layout and/or + the script. For example, some horizontal layouts like + Arabic can make use of vertical kerning adjustments + between successive glyphs. A vertical script can have + vertical kerning distances.</p> + </li> + <li> + <p>Kerning distances are expressed in grid units. They + are usually oriented in the <i>X</i> axis, which + means that a negative value indicates that two glyphs + must be set closer in a horizontal layout.</p> + </li> + </ul> + + <p>Note that OpenType fonts (OTF) provide two distinct + mechanisms for kerning, using the ‘kern’ and + ‘GPOS’ tables, respectively, which are part of + the OTF files. Older fonts only contain the former, while + recent fonts contain both tables or even + ‘GPOS’ data only. FreeType only supports + kerning via the (rather simple) ‘kern’ table. + For the interpretation of kerning data in the (highly + sophisticated) ‘GPOS’ table you need a + higher-level library + like <a href="http://icu-project.org/">ICU</a> or + <a href="http://harfbuzz.org">HarfBuzz</a> since it can be + context dependent (this is, the kerning may vary depending + on the position within a text string, for example).</p> + + + <h3 id="section-2">2. Applying kerning</h3> + + <p>Applying kerning when rendering text is a rather easy + process. It merely consists in adding the scaled kern + distance to the pen position before rendering the next + glyph. However, the typographically correct renderer must + take a few more details in consideration.</p> + + <p>The ‘sliding dot’ problem is a good example: + Many font faces include a kerning distance between capital + letters like ‘T’ or ‘F’ and a + following dot (‘.’), in order to slide the + latter glyph just right to their main leg.</p> + + <p align="center"> + <img src="twlewis1.png" + height="38" + width="314" + alt="example for sliding dots"> + </p> + + <p>This sometimes requires additional adjustments between + the dot and the letter following it, depending on the + shapes of the enclosing letters. When applying + ‘standard’ kerning adjustments, the previous + sentence would become</p> + + <p align="center"> + <img src="twlewis2.png" + height="36" + width="115" + alt="example for too much kerning"> + </p> + + <p>This is clearly too contracted. The solution here, as + exhibited in the first example, is to only slide the dots + if the conditions fit. Of course, this requires a certain + knowledge of the text's meaning, and this is exactly what + ‘GPOS’ kerning is good for: Depending on the + context, different kerning values can be applied to get a + typographically correct result.</p> + </div> + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 07-Dec-2014</p> + </div> + </div> + </div> + + + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="index.html">FreeType Glyph Conventions</a> + </li> + <li class="tertiary"> + <a href="glyphs-1.html">Basic Typographic Concepts</a> + </li> + <li class="tertiary"> + <a href="glyphs-2.html">Glyph Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-3.html">Glyph Metrics</a> + </li> + <li class="tertiary"> + <a href="glyphs-4.html" class="current">Kerning</a> + </li> + <li class="tertiary"> + <a href="glyphs-5.html">Text Processing</a> + </li> + <li class="tertiary"> + <a href="glyphs-6.html">FreeType Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-7.html">FreeType Bitmaps</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> + +<div id="TOC-bottom"> +</div> </body> </html> diff --git a/lib/freetype/docs/glyphs/glyphs-5.html b/lib/freetype/docs/glyphs/glyphs-5.html index 65f2de441..0a12e0359 100644 --- a/lib/freetype/docs/glyphs/glyphs-5.html +++ b/lib/freetype/docs/glyphs/glyphs-5.html @@ -1,484 +1,464 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en" - "http://www.w3.org/TR/REC-html40/loose.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + <head> <meta http-equiv="Content-Type" - content="text/html; charset=iso-8859-1"> + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> <meta name="Author" content="David Turner"> - <title>FreeType Glyph Conventions</title> + + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + + <title>FreeType Glyph Conventions / V</title> </head> -<body text="#000000" - bgcolor="#FFFFFF" - link="#0000EF" - vlink="#51188E" - alink="#FF0000"> - -<h1 align=center> - FreeType Glyph Conventions -</h1> - -<h2 align=center> - Version 2.1 -</h2> - -<h3 align=center> - Copyright 1998-2000 David Turner (<a - href="mailto:david@freetype.org">david@freetype.org</a>)<br> - Copyright 2000 The FreeType Development Team (<a - href="mailto:devel@freetype.org">devel@freetype.org</a>) -</h3> - -<center> -<table width="65%"> -<tr><td> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-4.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-6.html">Next</a> - </td> - </tr> - </table> - </center> - - <p><hr></p> - - <table width="100%"> - <tr bgcolor="#CCCCFF" - valign=center><td> - <h2> - V. Text processing - </h2> - </td></tr> - </table> - - <p>This section demonstrates how to use the concepts previously defined - to render text, whatever the layout you use.</p> - - - <a name="section-1"> - <h3> - 1. Writing simple text strings - </h3> - - <p>In this first example, we will generate a simple string of Roman - text, i.e. with a horizontal left-to-right layout. Using exclusively - pixel metrics, the process looks like: - - <tt> - <ol> - <li> - Convert the character string into a series of glyph - indices. - </li> - <li> - Place the pen to the cursor position. - </li> - <li> - Get or load the glyph image. - </li> - <li> - Translate the glyph so that its 'origin' matches the pen position. - </li> - <li> - Render the glyph to the target device. - </li> - <li> - Increment the pen position by the glyph's advance width in pixels. - </li> - <li> - Start over at step 3 for each of the remaining glyphs. - </li> - <li> - When all glyphs are done, set the text cursor to the new pen - position. - </li> - </ol> - </tt> - - <p>Note that kerning isn't part of this algorithm.</p> - - - <a name="section-2"> - <h3> - 2. Sub-pixel positioning - </h3> - - <p>It is somewhat useful to use sub-pixel positioning when rendering - text. This is crucial, for example, to provide semi-WYSIWYG text - layouts. Text rendering is very similar to the algorithm described in - subsection 1, with the following few differences:</p> - - <ul> - <li> - The pen position is expressed in fractional pixels. - </li> - <li> - Because translating a hinted outline by a non-integer distance will - ruin its grid-fitting, the position of the glyph origin must be - rounded before rendering the character image. - </li> - <li> - The advance width is expressed in fractional pixels, and isn't - necessarily an integer. - </li> - </ol> - - <p>Here an improved version of the algorithm:</p> - - <tt> - <ol> - <li> - Convert the character string into a series of glyph - indices. - </li> - <li> - Place the pen to the cursor position. This can be a non-integer - point. - </li> - <li> - Get or load the glyph image. - </li> - <li> - Translate the glyph so that its "origin" matches the rounded pen - position. - </li> - <li> - Render the glyph to the target device. - </li> - <li> - Increment the pen position by the glyph's advance width in - fractional pixels. - </li> - <li> - Start over at step 3 for each of the remaining glyphs. - </li> - <li> - When all glyphs are done, set the text cursor to the new pen - position. - </li> - </ol> - </tt> - - <p>Note that with fractional pixel positioning, the space between two - given letters isn't fixed, but determined by the accumulation of - previous rounding errors in glyph positioning.</p> - - - <a name="section-3"> - <h3> - 3. Simple kerning - </h3> - - <p>Adding kerning to the basic text rendering algorithm is easy: When a - kerning pair is found, simply add the scaled kerning distance to the pen - position before step 4. Of course, the distance should be rounded - in the case of algorithm 1, though it doesn't need to for - algorithm 2. This gives us:</p> - - <p>Algorithm 1 with kerning:</p> - - <tt> - <ol> - <li> - Convert the character string into a series of glyph - indices. - </li> - <li> - Place the pen to the cursor position. - </li> - <li> - Get or load the glyph image. - </li> - <li> - Add the rounded scaled kerning distance, if any, to the pen - position. - </li> - <li> - Translate the glyph so that its "origin" matches the pen position. - </li> - <li> - Render the glyph to the target device. - </li> - <li> - Increment the pen position by the glyph's advance width in pixels. - </li> - <li> - Start over at step 3 for each of the remaining glyphs. - </li> - </ol> - </tt> - - <p>Algorithm 2 with kerning:</p> - - <tt> - <ol> - <li> - Convert the character string into a series of glyph - indices. - </li> - <li> - Place the pen to the cursor position. - </li> - <li> - Get or load the glyph image. - </li> - <li> - Add the scaled unrounded kerning distance, if any, to the pen - position. - </li> - <li> - Translate the glyph so that its "origin" matches the rounded pen - position. - </li> - <li> - Render the glyph to the target device. - </li> - <li> - Increment the pen position by the glyph's advance width in - fractional pixels. - </li> - <li> - Start over at step 3 for each of the remaining glyphs. - </li> - </ol> - </tt> - - Of course, the algorithm described in section IV can also be - applied to prevent the sliding dot problem if one wants to. - - - <a name="section-4"> - <h3> - 4. Right-to-left layout - </h3> - - <p>The process of laying out Arabic or Hebrew text is extremely similar. - The only difference is that the pen position must be decremented before - the glyph rendering (remember: the advance width is always positive, - even for Arabic glyphs).</p> - - <p>Right-to-left algorithm 1:</p> - - <tt> - <ol> - <li> - Convert the character string into a series of glyph - indices. - </li> - <li> - Place the pen to the cursor position. - </li> - <li> - Get or load the glyph image. - </li> - <li> - Decrement the pen position by the glyph's advance width in pixels. - </li> - <li> - Translate the glyph so that its "origin" matches the pen position. - </li> - <li> - Render the glyph to the target device. - </li> - <li> - Start over at step 3 for each of the remaining glyphs. - </li> - </ol> - </tt> - - <p>The changes to algorithm 2, as well as the inclusion of kerning - are left as an exercise to the reader.</p> - - - <a name="section-5"> - <h3> - 5. Vertical layouts - </h3> - - <p>Laying out vertical text uses exactly the same processes, with the - following significant differences:</p> - - <ul> - <li> - <p>The baseline is vertical, and the vertical metrics must be used - instead of the horizontal one.</p> - </li> - <li> - <p>The left bearing is usually negative, but this doesn't change the - fact that the glyph origin must be located on the baseline.</p> - </li> - <li> - The advance height is always positive, so the pen position must be - decremented if one wants to write top to bottom (assuming the - <i>Y</i> axis is oriented upwards). - </li> - </ul> - - <p>Here the algorithm:</p> - - <tt> - <ol> - <li> - Convert the character string into a series of glyph - indices. - </li> - <li> - Place the pen to the cursor position. - </li> - <li> - Get or load the glyph image. - </li> - <li> - Translate the glyph so that its "origin" matches the pen position. - </li> - <li> - Render the glyph to the target device. - </li> - <li> - Decrement the vertical pen position by the glyph's advance height - in pixels. - </li> - <li> - Start over at step 3 for each of the remaining glyphs. - </li> - <li> - When all glyphs are done, set the text cursor to the new pen - position. - </li> - </ol> - </tt> - - - <a name="section-6"> - <h3> - 6. WYSIWYG text layouts - </h3> - - <p>As you probably know, the acronym WYSIWYG stands for "What You See Is - What You Get". Basically, this means that the output of a document on - the screen should match "perfectly" its printed version. A - <em>true</em> WYSIWYG system requires two things:</p> - - <ul> - <li> - <p><em>device-independent text layout</em></p> - - <p>This means that the document's formatting is the same on the - screen than on any printed output, including line breaks, - justification, ligatures, fonts, position of inline images, etc.</p> - </li> - <li> - <p><em>matching display and print character sizes</em></p> - - <p>The displayed size of a given character should match its - dimensions when printed. For example, a text string which is - exactly 1 inch tall when printed should also appear 1 inch - tall on the screen (when using a scale of 100%).</p> - </li> - </ul> - - <p>It is clear that matching sizes cannot be possible if the computer - has no knowledge of the physical resolutions of the display device(s) it - is using. And of course, this is the most common case! That is not too - unfortunate, however, because most users really don't care about this - feature. Legibility is much more important.</p> - - <p>When the Mac appeared, Apple decided to choose a resolution of - 72 dpi to describe the Macintosh screen to the font sub-system - (whatever the monitor used). This choice was most probably driven by - the fact that, at this resolution, 1 point equals exactly - 1 pixel. However, it neglected one crucial fact: As most users - tend to choose a document character size between 10 and 14 points, - the resultant displayed text was rather small and not too legible - without scaling. Microsoft engineers took notice of this problem and - chose a resolution of 96 dpi on Windows, which resulted in slightly - larger, and more legible, displayed characters (for the same printed - text size).</p> - - <p>These distinct resolutions explain some differences when displaying - text at the same character size on a Mac and a Windows machine. - Moreover, it is not unusual to find some TrueType fonts with enhanced - hinting (technical note: through delta-hinting) for the sizes of 10, 12, - 14 and 16 points at 96 dpi.</p> - - <p>The term <em>device-independent text</em> is, unfortunately, often - abused. For example, many word processors, including MS Word, do - not really use device-independent glyph positioning algorithms when - laying out text. Rather, they use the target printer's resolution to - compute <em>hinted</em> glyph metrics for the layout. Though it - guarantees that the printed version is always the "nicest" it can be, - especially for very low resolution printers (like dot-matrix), it has a - very sad effect: Changing the printer can have dramatic effects on the - <em>whole</em> document layout, especially if it makes strong use of - justification, uses few page breaks, etc.</p> - - <p>Because glyph metrics vary slightly when the resolution changes (due - to hinting), line breaks can change enormously, when these differences - accumulate over long runs of text. Try for example printing a very long - document (with no page breaks) on a 300 dpi ink-jet printer, then - the same one on a 3000 dpi laser printer: You will be extremely - lucky if your final page count didn't change between the prints! Of - course, we can still call this WYSIWYG, as long as the printer - resolution is fixed.</p> - - <p>Some applications, like Adobe Acrobat, which targeted - device-independent placement from the start, do not suffer from this - problem. There are two ways to achieve this: either use the scaled and - unhinted glyph metrics when laying out text both in the rendering and - printing processes, or simply use whatever metrics you want and store - them with the text in order to get sure they are printed the same on all - devices (the latter being probably the best solution, as it also enables - font substitution without breaking text layouts).</p> - - <p>Just like matching sizes, device-independent placement isn't - necessarily a feature that most users want. However, it is pretty clear - that for any kind of professional document processing work, it - <em>is</em> a requirement.</p> - - - <p><hr></p> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-4.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-6.html">Next</a> - </td> - </tr> - </table> - </center> - -</td></tr> -</table> -</center> + +<body> + +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> Glyph + Conventions / V</h1> +</div> + + +<div id="wrapper"> + +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> + + + <!-- ************************************************** --> + + <div id="text-processing"> + <h2>V. Text Processing</h2> + + <p>This section demonstrate algorithms which use the + concepts previously defined to render text, whatever + layout you use. It assumes <em>simple</em> text handling + suitable for scripts like Latin or Cyrillic, using a + one-to-one relationship between input character codes and + output glyphs indices. Scripts like Arabic or Khmer, + which need a ‘shaping engine’ to do the + character code to glyph index conversion, are beyond the + scope (and should be done by proper layout engines + like <a href="http://www.pango.org/">Pango</a> + anyway).</p> + + + <h3 id="section-1">1. Writing simple text strings</h3> + + <p>In this first example, we will generate a simple string + of text in the Latin script, i.e. with a horizontal + left-to-right layout. Using exclusively pixel metrics, + the process looks like: + + <ol class="algorithm"> + <li> + Convert the character string into a series of glyph + indices. + </li> + <li> + Place the pen to the cursor position. + </li> + <li> + Get or load the glyph image. + </li> + <li> + Translate the glyph so that its ‘origin’ + matches the pen position. + </li> + <li> + Render the glyph to the target device. + </li> + <li> + Increment the pen position by the glyph's advance + width (in pixels). + </li> + <li> + Start over at step 3 for each of the remaining + glyphs. + </li> + <li> + When all glyphs are done, set the text cursor to the + new pen position. + </li> + </ol> + + <p>Note that kerning isn't part of this algorithm.</p> + + + <h3 id="section-2">2. Pseudo-subpixel positioning</h3> + + <p>It is somewhat useful to use subpixel positioning when + rendering text. This is crucial, for example, to provide + semi-WYSIWYG text layouts. Text rendering is very similar + to the algorithm described in subsection 1, with the + following few differences:</p> + + <ul> + <li> + <p>The pen position is expressed in fractional + pixels.</p> + </li> + <li> + <p>Because translating a hinted outline by a non-integer + distance will ruin its grid-fitting, the position of + the glyph origin must be rounded before rendering the + character image.</p> + </li> + <li> + <p>The advance width is expressed in fractional pixels, + and isn't necessarily an integer.</p> + </li> + </ul> + + <p>Here an improved version of the algorithm:</p> + + <ol class="algorithm"> + <li> + Convert the character string into a series of glyph + indices. + </li> + <li> + Place the pen to the cursor position. This can be a + non-integer point. + </li> + <li> + Get or load the glyph image. + </li> + <li> + Translate the glyph so that its ‘origin’ + matches the rounded pen position. + </li> + <li> + Render the glyph to the target device. + </li> + <li> + Increment the pen position by the glyph's advance width + in fractional pixels. + </li> + <li> + Start over at step 3 for each of the remaining + glyphs. + </li> + <li> + When all glyphs are done, set the text cursor to the new + pen position. + </li> + </ol> + + <p>Note that with fractional pixel positioning, the space + between two given letters isn't fixed, but determined by + the accumulation of previous rounding errors in glyph + positioning. For auto-hinted glyphs, this problem can be + alleviated by using the <tt>lsb_delta</tt> + and <tt>rsb_delta</tt> values (see the documentation of + the <a href="../reference/ft2-base_interface.html#FT_GlyphSlotRec">FT_GlyphSlotRec</a> + structure for more details).</p> + + <p>TODO: Real subpixel positioning with glyph shifting + before hinting.</p> + + + <h3 id="section-3">3. Simple kerning</h3> + + <p>Adding kerning to the basic text rendering algorithm is + easy: When a kerning pair is found, simply add the scaled + kerning distance to the pen position before step 4. + Of course, the distance should be rounded in the case of + algorithm 1, though it doesn't need to for + algorithm 2. This gives us:</p> + + <p>Algorithm 1 with kerning:</p> + + <ol class="algorithm"> + <li> + Convert the character string into a series of glyph + indices. + </li> + <li> + Place the pen to the cursor position. + </li> + <li> + Get or load the glyph image. + </li> + <li> + Add the rounded scaled kerning distance, if any, to the + pen position. + </li> + <li> + Translate the glyph so that its ‘origin’ + matches the pen position. + </li> + <li> + Render the glyph to the target device. + </li> + <li> + Increment the pen position by the glyph's advance width + in pixels. + </li> + <li> + Start over at step 3 for each of the remaining + glyphs. + </li> + </ol> + + <p>Algorithm 2 with kerning:</p> + + <ol class="algorithm"> + <li> + Convert the character string into a series of glyph + indices. + </li> + <li> + Place the pen to the cursor position. + </li> + <li> + Get or load the glyph image. + </li> + <li> + Add the scaled unrounded kerning distance, if any, to + the pen position. + </li> + <li> + Translate the glyph so that its ‘origin’ + matches the rounded pen position. + </li> + <li> + Render the glyph to the target device. + </li> + <li> + Increment the pen position by the glyph's advance + width in fractional pixels. + </li> + <li> + Start over at step 3 for each of the remaining + glyphs. + </li> + </ol> + + + <h3 id="section-4">4. Right-to-left layout</h3> + + <p>The process of laying out right-to-left scripts like + (modern) Hebrew text is very similar. The only difference + is that the pen position must be decremented before the + glyph rendering (remember: the advance width is always + positive, even for Hebrew glyphs).</p> + + <p>Right-to-left algorithm 1:</p> + + <ol class="algorithm"> + <li> + Convert the character string into a series of glyph + indices. + </li> + <li> + Place the pen to the cursor position. + </li> + <li> + Get or load the glyph image. + </li> + <li> + Decrement the pen position by the glyph's advance + width in pixels. + </li> + <li> + Translate the glyph so that its ‘origin’ + matches the pen position. + </li> + <li> + Render the glyph to the target device. + </li> + <li> + Start over at step 3 for each of the remaining + glyphs. + </li> + </ol> + + <p>The changes to algorithm 2, as well as the inclusion + of kerning are left as an exercise to the reader.</p> + + + <h3 id="section-5">5. Vertical layouts</h3> + + <p>Laying out vertical text uses exactly the same processes, + with the following significant differences:</p> + + <ul> + <li> + <p>The baseline is vertical, and the vertical metrics + must be used instead of the horizontal one.</p> + </li> + <li> + <p>The left bearing is usually negative, but this + doesn't change the fact that the glyph origin must be + located on the baseline.</p> + </li> + <li> + <p>The advance height is always positive, so the pen + position must be decremented if one wants to write top + to bottom (assuming the <i>Y</i> axis is oriented + upwards).</p> + </li> + </ul> + + <p>Here the algorithm:</p> + + <ol class="algorithm"> + <li> + Convert the character string into a series of glyph + indices. + </li> + <li> + Place the pen to the cursor position. + </li> + <li> + Get or load the glyph image. + </li> + <li> + Translate the glyph so that its ‘origin’ + matches the pen position. + </li> + <li> + Render the glyph to the target device. + </li> + <li> + Decrement the vertical pen position by the glyph's + advance height in pixels. + </li> + <li> + Start over at step 3 for each of the remaining + glyphs. + </li> + <li> + When all glyphs are done, set the text cursor to the new + pen position. + </li> + </ol> + </div> + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 07-Dec-2014</p> + </div> + </div> + </div> + + + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="index.html">FreeType Glyph Conventions</a> + </li> + <li class="tertiary"> + <a href="glyphs-1.html">Basic Typographic Concepts</a> + </li> + <li class="tertiary"> + <a href="glyphs-2.html">Glyph Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-3.html">Glyph Metrics</a> + </li> + <li class="tertiary"> + <a href="glyphs-4.html">Kerning</a> + </li> + <li class="tertiary"> + <a href="glyphs-5.html" class="current">Text Processing</a> + </li> + <li class="tertiary"> + <a href="glyphs-6.html">FreeType Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-7.html">FreeType Bitmaps</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> + +<div id="TOC-bottom"> +</div> </body> </html> diff --git a/lib/freetype/docs/glyphs/glyphs-6.html b/lib/freetype/docs/glyphs/glyphs-6.html index 30bd4af02..5c5e745c5 100644 --- a/lib/freetype/docs/glyphs/glyphs-6.html +++ b/lib/freetype/docs/glyphs/glyphs-6.html @@ -1,452 +1,537 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en" - "http://www.w3.org/TR/REC-html40/loose.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + <head> <meta http-equiv="Content-Type" - content="text/html; charset=iso-8859-1"> + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> <meta name="Author" content="David Turner"> - <title>FreeType Glyph Conventions</title> + + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + + <title>FreeType Glyph Conventions / VI</title> </head> -<body text="#000000" - bgcolor="#FFFFFF" - link="#0000EF" - vlink="#51188E" - alink="#FF0000"> - -<h1 align=center> - FreeType Glyph Conventions -</h1> - -<h2 align=center> - Version 2.1 -</h2> - -<h3 align=center> - Copyright 1998-2000 David Turner (<a - href="mailto:david@freetype.org">david@freetype.org</a>)<br> - Copyright 2000, 2006, 2011 The FreeType Development Team (<a - href="mailto:devel@freetype.org">devel@freetype.org</a>) -</h3> - -<center> -<table width="65%"> -<tr><td> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-5.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-7.html">Next</a> - </td> - </tr> - </table> - </center> - - <p><hr></p> - - <table width="100%"> - <tr bgcolor="#CCCCFF" - valign=center><td> - <h2> - VI. FreeType outlines - </h2> - </td></tr> - </table> - - <p>The purpose of this section is to present the way FreeType manages - vectorial outlines, as well as the most common operations that can be - applied on them.</p> - - <a name="section-1"> - <h3> - 1. FreeType outline description and structure - </h3> - - <h4> - a. Outline curve decomposition - </h4> - - <p>An outline is described as a series of closed contours in the 2D - plane. Each contour is made of a series of line segments and - Bézier arcs. Depending on the file format, these can be - second-order or third-order polynomials. The former are also called - quadratic or conic arcs, and they are used in the TrueType format. - The latter are called cubic arcs and are mostly used in the - Type 1 format.</p> - - <p>Each arc is described through a series of start, end, and control - points. Each point of the outline has a specific tag which indicates - whether it is used to describe a line segment or an arc. The tags can - take the following values:</p> - - <center> - <table cellspacing=5 - cellpadding=5 - width="80%"> - <tr VALIGN=TOP> - <td valign=top> - <tt>FT_CURVE_TAG_ON</tt> - </td> - <td valign=top> - <p>Used when the point is "on" the curve. This corresponds to - start and end points of segments and arcs. The other tags specify - what is called an "off" point, i.e. a point which isn't located on - the contour itself, but serves as a control point for a - Bézier arc.</p> - </td> - </tr> - - <tr> - <td valign=top> - <tt>FT_CURVE_TAG_CONIC</tt> - </td> - <td valign=top> - <p>Used for an "off" point used to control a conic Bézier - arc.</p> - </td> - </tr> - - <tr> - <td valign=top> - <tt>FT_CURVE_TAG_CUBIC</tt> - </td> - <td valign=top> - <p>Used for an "off" point used to control a cubic Bézier - arc.</p> - </td> - </tr> - </table> - </center> - - <p>Use the <tt>FT_CURVE_TAG(tag)</tt> macro to filter out other, - internally used flags. - - <p>The following rules are applied to decompose the contour's points - into segments and arcs:</p> - - <ul> - <li> - Two successive "on" points indicate a line segment joining them. - </li> - <li> - One conic "off" point amidst two "on" points indicates a conic - Bézier arc, the "off" point being the control point, and - the "on" ones the start and end points. - </li> - <li> - Two successive cubic "off" points amidst two "on" points indicate - a cubic Bézier arc. There must be exactly two cubic - control points and two "on" points for each cubic arc (using a - single cubic "off" point between two "on" points is forbidden, for - example). - </li> - <li> - Two successive conic "off" points forces the rasterizer to create - (during the scan-line conversion process exclusively) a virtual - "on" point amidst them, at their exact middle. This greatly - facilitates the definition of successive conic Bézier arcs. - Moreover, it is the way outlines are described in the TrueType - specification. - </li> - <li> - The last point in a contour uses the first as an end point to - create a closed contour. For example, if the last two points of a - contour were an "on" point followed by a conic "off" point, the - first point in the contour would be used as final point to create - an "on" – "off" – "on" sequence as described above. - </li> - <li> - The first point in a contour can be a conic "off" point itself; in - that case, use the last point of the contour as the contour's - starting point. If the last point is a conic "off" point itself, - start the contour with the virtual "on" point between the last and - first point of the contour. - </li> - </ul> - - <p>Note that it is possible to mix conic and cubic arcs in a single - contour, even though no current font driver produces such - outlines.</p> - - <center> - <table> - <tr> - <td> - <img src="points_segment.png" - height=166 width=221 - alt="segment example"> - </td> - <td> - <img src="points_conic.png" - height=183 width=236 - alt="conic arc example"> - </td> - </tr> - <tr> - <td> - <img src="points_cubic.png" - height=162 width=214 - alt="cubic arc example"> - </td> - <td> - <img src="points_conic2.png" - height=204 width=225 - alt="cubic arc with virtual 'on' point"> - </td> - </tr> - </table> - </center> - - - <h4> - b. Outline descriptor - </h4> - - <p>A FreeType outline is described through a simple structure:</p> - - <center> - <table cellspacing=3 - cellpadding=3> - <caption> - <b><tt>FT_Outline</tt></b> - </caption> - - <tr> - <td> - <tt>n_points</tt> - </td> - <td> - the number of points in the outline - </td> - </tr> - <tr> - <td> - <tt>n_contours</tt> - </td> - <td> - the number of contours in the outline - </td> - </tr> - <tr> - <td> - <tt>points</tt> - </td> - <td> - array of point coordinates - </td> - </tr> - <tr> - <td> - <tt>contours</tt> - </td> - <td> - array of contour end indices - </td> - </tr> - <tr> - <td> - <tt>tags</tt> - </td> - <td> - array of point flags - </td> - </tr> - </table> - </center> - - <p>Here, <tt>points</tt> is a pointer to an array of - <tt>FT_Vector</tt> records, used to store the vectorial coordinates of - each outline point. These are expressed in 1/64th of a pixel, which - is also known as the <em>26.6 fixed-point format</em>.</p> - - <p><tt>contours</tt> is an array of point indices used to delimit - contours in the outline. For example, the first contour always starts - at point 0, and ends at point <tt>contours[0]</tt>. The second - contour starts at point <tt>contours[0]+1</tt> and ends at - <tt>contours[1]</tt>, etc. To traverse these points in a callback - based manner, use <tt>FT_Outline_Decompose()</tt>.</p> - - <p>Note that each contour is closed, and that <tt>n_points</tt> should - be equal to <tt>contours[n_contours-1]+1</tt> for a valid outline.</p> - - <p>Finally, <tt>tags</tt> is an array of bytes, used to store each - outline point's tag.</p> - - - <a name="section-2"> - <h3> - 2. Bounding and control box computations - </h3> - - <p>A <em>bounding box</em> (also called <em>bbox</em>) is simply a - rectangle that completely encloses the shape of a given outline. The - interesting case is the smallest bounding box possible, and in the - following we subsume this under the term "bounding box". Because of the - way arcs are defined, Bézier control points are not necessarily - contained within an outline's (smallest) bounding box.</p> - - <p>This situation happens when one Bézier arc is, for example, - the upper edge of an outline and an "off" point happens to be above the - bbox. However, it is very rare in the case of character outlines - because most font designers and creation tools always place "on" points - at the extrema of each curved edges, as it makes hinting much - easier.</p> - - <p>We thus define the <em>control box</em> (also called <em>cbox</em>) - as the smallest possible rectangle that encloses all points of a given - outline (including its "off" points). Clearly, it always includes the - bbox, and equates it in most cases.</p> - - <p>Unlike the bbox, the cbox is much faster to compute.</p> - - <center> - <table> - <tr> - <td> - <img src="bbox1.png" - height=264 width=228 - alt="a glyph with different bbox and cbox"> - </td> - <td> - <img src="bbox2.png" - height=229 width=217 - alt="a glyph with identical bbox and cbox"> - </td> - </tr> - </table> - </center> - - <p>Control and bounding boxes can be computed automatically through the - functions <tt>FT_Outline_Get_CBox()</tt> and - <tt>FT_Outline_Get_BBox()</tt>. The former function is always very - fast, while the latter <em>may</em> be slow in the case of "outside" - control points (as it needs to find the extreme of conic and cubic arcs - for "perfect" computations). If this isn't the case, it is as fast as - computing the control box. - - <p>Note also that even though most glyph outlines have equal cbox and - bbox to ease hinting, this is not necessary the case anymore when a - transformation like rotation is applied to them.</p> - - - <a name="section-3"> - <h3> - 3. Coordinates, scaling and grid-fitting - </h3> - - <p>An outline point's vectorial coordinates are expressed in the - 26.6 format, i.e. in 1/64th of a pixel, hence the coordinates - (1.0,-2.5) is stored as the integer pair (x:64,y:-192).</p> - - <p>After a master glyph outline is scaled from the EM grid to the - current character dimensions, the hinter or grid-fitter is in charge of - aligning important outline points (mainly edge delimiters) to the pixel - grid. Even though this process is much too complex to be described in a - few lines, its purpose is mainly to round point positions, while trying - to preserve important properties like widths, stems, etc.</p> - - <p>The following operations can be used to round vectorial distances in - the 26.6 format to the grid:</p> - - <pre> - round( x ) == ( x + 32 ) & -64 - floor( x ) == x & -64 - ceiling( x ) == ( x + 63 ) & -64</pre> - - <p>Once a glyph outline is grid-fitted or transformed, it often is - interesting to compute the glyph image's pixel dimensions before - rendering it. To do so, one has to consider the following:</p> - - <p>The scan-line converter draws all the pixels whose <em>centers</em> - fall inside the glyph shape. It can also detect <em>drop-outs</em>, - i.e. discontinuities coming from extremely thin shape fragments, in - order to draw the "missing" pixels. These new pixels are always located - at a distance less than half of a pixel but it is not easy to predict - where they will appear before rendering.</p> - - <p>This leads to the following computations:</p> - - <ul> - <li> - <p>compute the bbox</p> - </li> - <li> - <p>grid-fit the bounding box with the following:</p> - - <pre> - xmin = floor( bbox.xMin ) - xmax = ceiling( bbox.xMax ) - ymin = floor( bbox.yMin ) - ymax = ceiling( bbox.yMax )</pre> - </li> - <li> - return pixel dimensions, i.e. - - <pre> - width = (xmax - xmin)/64</pre> - - and - - <pre> - height = (ymax - ymin)/64</pre> - </li> - </ul> - - <p>By grid-fitting the bounding box, it is guaranteed that all the pixel - centers that are to be drawn, <em>including those coming from drop-out - control</em>, will be <em>within</em> the adjusted box. Then the box's - dimensions in pixels can be computed.</p> - - <p>Note also that, when translating a grid-fitted outline, one should - <em>always use integer distances</em> to move an outline in the 2D - plane. Otherwise, glyph edges won't be aligned on the pixel grid - anymore, and the hinter's work will be lost, producing <em>very low - quality </em>bitmaps and pixmaps.</p> - - - <p><hr></p> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-5.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - <a href="glyphs-7.html">Next</a> - </td> - </tr> - </table> - </center> - -</td></tr> -</table> -</center> - -<font size=-1>Last update: 06-Mar-2011</font> + +<body> + +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> Glyph + Conventions / VI</h1> +</div> + + +<div id="wrapper"> + +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> + + + <!-- ************************************************** --> + + <div id="freetype-outlines"> + <h2>VI. FreeType outlines</h2> + + <p>The purpose of this section is to present the way + FreeType manages vectorial outlines, as well as the most + common operations that can be applied on them.</p> + + <h3 id="section-1">1. FreeType outline description and + structure</h3> + + <h4>a. Outline curve decomposition</h4> + + <p>An outline is described as a series of closed contours in + the 2D plane. Each contour is made of a series of line + segments and Bézier arcs. Depending on the file + format, these can be second-order or third-order + polynomials. The former are also called quadratic or + conic arcs, and they are used in the TrueType format. The + latter are called cubic arcs and are mostly used in the + PostScript Type 1 and Type formats.</p> + + <p>Each arc is described through a series of start, end, and + control points. Each point of the outline has a specific + tag which indicates whether it is describes a line segment + or an arc. The tags can take the following values:</p> + + <table> + <tr> + <td valign="top"> + <p><tt>FT_CURVE_TAG_ON</tt></p> + </td> + <td valign="top"> + <p>Used when the point is ‘on’ the curve. + This corresponds to start and end points of segments + and arcs. The other tags specify what is called an + ‘off’ point, i.e., a point which isn't + located on the contour itself, but serves as a + control point for a Bézier arc.</p> + </td> + </tr> + <tr> + <td valign="top"> + <p><tt>FT_CURVE_TAG_CONIC</tt></p> + </td> + <td valign="top"> + <p>Used for an ‘off’ point used to control + a conic Bézier arc.</p> + </td> + </tr> + <tr> + <td valign="top"> + <p><tt>FT_CURVE_TAG_CUBIC</tt></p> + </td> + <td valign="top"> + <p>Used for an ‘off’ point used to control + a cubic Bézier arc.</p> + </td> + </tr> + </table> + + <p>Use the <tt>FT_CURVE_TAG(tag)</tt> macro to filter out + other, internally used flags. + + <p>The following rules are applied to decompose the + contour's points into segments and arcs:</p> + + <ul> + <li> + <p>Two successive ‘on’ points indicate a + line segment joining them.</p> + </li> + <li> + <p>One conic ‘off’ point between two + ‘on’ points indicates a conic + Bézier arc, the ‘off’ point being + the control point, and the ‘on’ ones the + start and end points.</p> + </li> + <li> + <p>Two successive cubic ‘off’ points between + two ‘on’ points indicate a cubic + Bézier arc. There must be exactly two cubic + control points and two ‘on’ points for + each cubic arc (using a single cubic ‘off’ + point between two ‘on’ points is + forbidden, for example).</p> + </li> + <li> + <p>Two successive conic ‘off’ points force + the rasterizer to create (during the scan-line + conversion process exclusively) a virtual + ‘on’ point inbetween, at their exact + middle. This greatly facilitates the definition of + successive conic Bézier arcs. Moreover, it is + the way outlines are described in the TrueType + specification.</p> + </li> + <li> + <p>The last point in a contour uses the first as an end + point to create a closed contour. For example, if the + last two points of a contour were an ‘on’ + point followed by a conic ‘off’ point, the + first point in the contour would be used as final + point to create an ‘on’ – + ‘off’ – ‘on’ sequence as + described above. + </li> + <li> + <p>The first point in a contour can be a conic + ‘off’ point itself; in that case, use the + last point of the contour as the contour's starting + point. If the last point is a conic ‘off’ + point itself, start the contour with the virtual + ‘on’ point between the last and first + point of the contour. + </li> + </ul> + + <p>Note that it is possible to mix conic and cubic arcs in a + single contour, however, no font driver of FreeType + produces such outlines currently.</p> + + <table> + <tr> + <td> + <img src="points_segment.png" + height="166" + width="221" + alt="segment example"> + </td> + <td> + <img src="points_conic.png" + height="183" + width="236" + alt="conic arc example"> + </td> + </tr> + <tr> + <td> + <img src="points_cubic.png" + height="162" + width="214" + alt="cubic arc example"> + </td> + <td> + <img src="points_conic2.png" + height="204" + width="225" + alt="cubic arc with virtual 'on' point"> + </td> + </tr> + </table> + + + <h4>b. The <tt>FT_Outline</tt> descriptor</h4> + + <p>A FreeType outline is described through a simple + structure + called <a href="../reference/ft2-outline_processing.html#FT_Outline"><tt>FT_Outline</tt></a>. + Right now, the following fields are of interest:</p> + + <table> + <caption> + <b><tt>FT_Outline</tt></b> + </caption> + <tbody> + <tr> + <td> + <tt>n_points</tt> + </td> + <td> + the number of points in the outline + </td> + </tr> + <tr> + <td> + <tt>n_contours</tt> + </td> + <td> + the number of contours in the outline + </td> + </tr> + <tr> + <td> + <tt>points</tt> + </td> + <td> + array of point coordinates + </td> + </tr> + <tr> + <td> + <tt>contours</tt> + </td> + <td> + array of contour end indices + </td> + </tr> + <tr> + <td> + <tt>tags</tt> + </td> + <td> + array of point flags + </td> + </tr> + </tbody> + </table> + + <p>Here, <tt>points</tt> is a pointer to an array of + <a href="../reference/ft2-basic_types.html#FT_Vector"><tt>FT_Vector</tt></a> + records, used to store the vectorial coordinates of each + outline point. These are expressed in 1/64th of a pixel, + which is also known as the <em>26.6 fixed-point + format</em>.</p> + + <p><tt>contours</tt> is an array of point indices to delimit + contours in the outline. For example, the first contour + always starts at point 0, and ends at + point <tt>contours[0]</tt>. The second contour starts at + point <tt>contours[0]+1</tt> and ends at + <tt>contours[1]</tt>, etc. To traverse these points in a + callback based manner, + use <a href="../reference/ft2-outline_processing.html#FT_Outline_Decompose"><tt>FT_Outline_Decompose</tt></a>.</p> + + <p>Note that each contour is closed, and that value + of <tt>n_points</tt> should be equal + to <tt>contours[n_contours-1]+1</tt> for a valid + outline.</p> + + <p>Finally, <tt>tags</tt> is an array of bytes, used to + store each outline point's tag.</p> + + + <h3 id="section-2">2. Bounding and control box + computations</h3> + + <p>As described earlier, a <em>bounding box</em> (also + called <em>bbox</em>) is simply a rectangle that + completely encloses the shape of a given outline. The + interesting case is the smallest bounding box possible, + and in the following we subsume this under the term + ‘bounding box’. Because of the way arcs are + defined, Bézier control points are not necessarily + contained within an outline's (smallest) bounding box.</p> + + <p>Such a situation happens if one Bézier arc is, for + example, the upper edge of an outline and an + ‘off’ point happens to be above the bbox. + However, it is very rare in the case of character outlines + because most font designers and creation tools always + place ‘on’ points at the extrema of each + curved edges (as both the TrueType and PostScript + specifications recommend), as it makes hinting much + easier.</p> + + <p>We thus define the <em>control box</em> (also + called <em>cbox</em>) as the smallest possible rectangle + that encloses all points of a given outline (including its + ‘off’ points). Clearly, it always includes + the bbox, and the two boxes are identical in most + cases.</p> + + <p>Unlike the bbox, the cbox is much faster to compute.</p> + + <table> + <tr> + <td> + <img src="bbox1.png" + height="264" + width="228" + alt="a glyph with different bbox and cbox"> + </td> + <td> + <img src="bbox2.png" + height="229" + width="217" + alt="a glyph with identical bbox and cbox"> + </td> + </tr> + </table> + + <p>Control and bounding boxes can be computed automatically + using the + functions <a href="../reference/ft2-outline_processing.html#FT_Outline_Get_CBox"><tt>FT_Outline_Get_CBox</tt></a> + and + <a href="../reference/ft2-outline_processing.html#FT_Outline_Get_BBox"><tt>FT_Outline_Get_BBox</tt></a>. + The former function is always very fast, while the + latter <em>may</em> be slow in the case of + ‘outside’ control points (as it needs to find + the extreme of conic and cubic arcs for + ‘perfect’ computations). If this isn't the + case, it is as fast as computing the control box. + + <p>Note also that even though most glyph outlines have equal + cbox and bbox values to ease hinting, this is not + necessarily the case if a transformation like rotation is + applied to them.</p> + + + <h3 id="section-3">3. Coordinates, scaling and + grid-fitting</h3> + + <p>An outline point's vectorial coordinates are expressed in + the 26.6 format, i.e. in 1/64th of a pixel, hence the + coordinates ‘(1.0,-2.5)’ is stored as the + integer pair ‘(64,-192)’, to name an + example.</p> + + <p>After a glyph outline is scaled from the EM grid (in font + units) to the current character dimensions, the hinter or + grid-fitter is in charge of aligning important outline + points (mainly edge delimiters) to the pixel grid. Even + though this process is much too complex to be described in + a few lines, its purpose is mainly to round point + positions, while trying to preserve important properties + like widths, stems, etc.</p> + + <p>The following operations can be used to round vectorial + distances in the 26.6 format to the grid:</p> + + <pre> +round( x ) == ( x + 32 ) & -64 +floor( x ) == x & -64 +ceiling( x ) == ( x + 63 ) & -64</pre> + + <p>Once a glyph outline is grid-fitted or transformed, it + often is interesting to compute the glyph image's pixel + dimensions before rendering it. To do so, one has to + consider the following:</p> + + <p>The scan-line converter draws all the pixels + whose <em>centers</em> fall inside the glyph shape. In + B/W rendering mode, it can also detect <em>drop-outs</em>, + i.e., discontinuities coming from extremely thin shape + fragments, in order to draw the ‘missing’ + pixels. These new pixels are always located at a distance + less than half of a pixel but it is not easy to predict + where they will appear before rendering.</p> + + <p>This leads to the following computations:</p> + + <ul> + <li> + <p>compute the bbox</p> + </li> + <li> + <p>grid-fit the bounding box with the following:</p> + + <pre> +xmin = floor( bbox.xMin ) +xmax = ceiling( bbox.xMax ) +ymin = floor( bbox.yMin ) +ymax = ceiling( bbox.yMax )</pre> + </li> + <li> + <p>return pixel dimensions, i.e.</p> + + <pre> +width = (xmax - xmin)/64</pre> + + <p>and</p> + + <pre> +height = (ymax - ymin)/64</pre> + </li> + </ul> + + <p>By grid-fitting the bounding box, it is guaranteed that + all the pixel centers that are to be drawn, <em>including + those coming from drop-out control</em>, will + be <em>within</em> the adjusted box. Then the box's + dimensions in pixels can be computed.</p> + + <p>Note also that, when translating a grid-fitted outline, one should + <em>always use integer distances</em> to move an outline + in the 2D plane. Otherwise, glyph edges won't be aligned + on the pixel grid anymore, and the hinter's work will be + lost, producing <em>very low quality</em> bitmaps and + pixmaps.</p> + </div> + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 07-Dec-2014</p> + </div> + </div> + </div> + + + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="index.html">FreeType Glyph Conventions</a> + </li> + <li class="tertiary"> + <a href="glyphs-1.html">Basic Typographic Concepts</a> + </li> + <li class="tertiary"> + <a href="glyphs-2.html">Glyph Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-3.html">Glyph Metrics</a> + </li> + <li class="tertiary"> + <a href="glyphs-4.html">Kerning</a> + </li> + <li class="tertiary"> + <a href="glyphs-5.html">Text Processing</a> + </li> + <li class="tertiary"> + <a href="glyphs-6.html" class="current">FreeType Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-7.html">FreeType Bitmaps</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> + +<div id="TOC-bottom"> +</div> </body> </html> diff --git a/lib/freetype/docs/glyphs/glyphs-7.html b/lib/freetype/docs/glyphs/glyphs-7.html index b57ba0662..ef134a1d8 100644 --- a/lib/freetype/docs/glyphs/glyphs-7.html +++ b/lib/freetype/docs/glyphs/glyphs-7.html @@ -1,356 +1,427 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en" - "http://www.w3.org/TR/REC-html40/loose.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + <head> <meta http-equiv="Content-Type" - content="text/html; charset=iso-8859-1"> + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> <meta name="Author" content="David Turner"> - <title>FreeType Glyph Conventions</title> + + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + + <title>FreeType Glyph Conventions / VII</title> </head> -<body text="#000000" - bgcolor="#FFFFFF" - link="#0000EF" - vlink="#51188E" - alink="#FF0000"> - -<h1 align=center> - FreeType Glyph Conventions -</h1> - -<h2 align=center> - Version 2.1 -</h2> - -<h3 align=center> - Copyright 1998-2000 David Turner (<a - href="mailto:david@freetype.org">david@freetype.org</a>)<br> - Copyright 2000 The FreeType Development Team (<a - href="mailto:devel@freetype.org">devel@freetype.org</a>) -</h3> - -<center> -<table width="65%"> -<tr><td> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-6.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - - </td> - </tr> - </table> - </center> - - <p><hr></p> - - <table width="100%"> - <tr bgcolor="#CCCCFF" - valign=center><td> - <h2> - VII. FreeType bitmaps - </h2> - </td></tr> - </table> - - <p>The purpose of this section is to present the way FreeType manages - bitmaps and pixmaps, and how they relate to the concepts previously - defined. The relationships between vectorial and pixel coordinates is - explained.</p> - - - <a name="section-1"> - <h3> - 1. Vectorial versus pixel coordinates - </h3> - - <p>This sub-section explains the differences between vectorial and pixel - coordinates. To make things clear, brackets will be used to describe - pixel coordinates, e.g. [3,5], while parentheses will be used for - vectorial ones, e.g. (-2,3.5).</p> - - <p>In the pixel case, as we use the <em>Y upwards</em> convention; - the coordinate [0,0] always refers to the <em>lower left pixel</em> of a - bitmap, while coordinate [width-1, rows-1] to its <em>upper right - pixel</em>.</p> - - <p>In the vectorial case, point coordinates are expressed in floating - units, like (1.25, -2.3). Such a position doesn't refer to a given - pixel, but simply to an immaterial point in the 2D plane.</p> - - <p>The pixels themselves are indeed <em>square boxes</em> of the 2D - plane, whose centers lie in half pixel coordinates. For example, the - lower left pixel of a bitmap is delimited by the square (0,0)-(1,1), its - center being at location (0.5,0.5).</p> - - <p>This introduces some differences when computing distances. For - example, the <em>length</em> in pixels of the line [0,0]-[10,0] is 11. - However, the vectorial distance between (0,0)-(10,0) covers exactly - 10 pixel centers, hence its length is 10.</p> - - <center> - <img src="grid_1.png" - height=390 width=402 - alt="bitmap and vector grid"> - </center> - - - <a name="section-2"> - <h3> - 2. FreeType bitmap and pixmap descriptor - </h3> - - <p>A bitmap or pixmap is described through a single structure, called - <tt>FT_Bitmap</tt>, defined in the file - <tt><freetype/ftimage.h></tt>. It is a simple descriptor whose - fields are:</p> - - <center> - <table cellspacing=3 - cellpadding=5 - width="80%"> - <caption> - <b><tt>FT_Bitmap</tt></b> - </caption> - - <tr> - <td valign=top> - <tt>rows</tt> - </td> - <td valign=top> - the number of rows, i.e. lines, in the bitmap - </td> - </tr> - - <tr> - <td valign=top> - <tt>width</tt> - </td> - <td valign=top> - the number of horizontal pixels in the bitmap - </td> - </tr> - - <tr> - <td valign=top> - <tt>pitch</tt> - </td> - <td valign=top> - its absolute value is the number of bytes per bitmap line; it can - be either positive or negative depending on the bitmap's vertical - orientation - </td> - </tr> - - <tr> - <td valign=top> - <tt>buffer</tt> - </td> - <td valign=top> - a typeless pointer to the bitmap pixel bufer - </td> - </tr> - - <tr> - <td valign=top> - <tt>pixel_mode</tt> - </td> - <td valign=top> - an enumeration used to describe the pixel format of the bitmap; - examples are <tt>ft_pixel_mode_mono</tt> for 1-bit monochrome - bitmaps and <tt>ft_pixel_mode_grays</tt> for 8-bit anti-aliased - "gray" values - </td> - </tr> - - <tr> - <td valign=top> - <tt>num_grays</tt> - </td> - <td valign=top> - this is only used for "gray" pixel modes, it gives the number of - gray levels used to describe the anti-aliased gray levels -- - 256 by default with FreeType 2 - </td> - </tr> - </table> - </center> - - - <p>Note that the sign of the <tt>pitch</tt> fields determines whether - the rows in the pixel buffer are stored in ascending or descending - order.</p> - - <p>Remember that FreeType uses the <em>Y upwards</em> convention in - the 2D plane, which means that a coordinate of (0,0) always refer to the - <em>lower-left corner</em> of a bitmap.</p> - - <p>If the pitch is positive, the rows are stored in decreasing vertical - position; the first bytes of the pixel buffer are part of the - <em>upper</em> bitmap row.</p> - - <p>On the opposite, if the pitch is negative, the first bytes of the - pixel buffer are part of the <em>lower</em> bitmap row.</p> - - <p>In all cases, one can see the pitch as the byte increment needed to - skip to the <em>next lower scanline</em> in a given bitmap buffer.</p> - - <center> - <table> - <tr> - <td> - <img src="up_flow.png" - height=261 width=275 - alt="negative 'pitch'"> - </td> - <td> - <img src="down_flow.png" - height=263 width=273 - alt="positive 'pitch'"> - </td> - </tr> - </table> - </center> - - <p>The "positive pitch" convention is very often used, though - some systems might need the other.</p> - - - <a name="section-3"> - <h3> - 3. Converting outlines into bitmaps and pixmaps - </h3> - - <p>Generating a bitmap or pixmap image from a vectorial image is easy - with FreeType. However, one must understand a few points regarding the - positioning of the outline in the 2D plane before converting it to a - bitmap:</p> - - <ul> - <li> - <p>The glyph loader and hinter always places the outline in the 2D - plane so that (0,0) matches its character origin. This means that - the glyph's outline, and corresponding bounding box, can be placed - anywhere in the 2D plane (see the graphics in section III).</p> - </li> - <li> - <p>The target bitmap's area is mapped to the 2D plane, with its - lower left corner at (0,0). This means that a bitmap or pixmap of - dimensions [<tt>w,h</tt>] will be mapped to a 2D rectangle window - delimited by (0,0)-(<tt>w,h</tt>).</p> - </li> - <li> - <p>When scan-converting the outline, everything that falls within - the bitmap window is rendered, the rest is ignored.</p> - </li> - - <p>A common mistake made by many developers when they begin using - FreeType is believing that a loaded outline can be directly rendered - in a bitmap of adequate dimensions. The following images illustrate - why this is a problem.</p> - - <ul> - <li> - The first image shows a loaded outline in the 2D plane. - </li> - <li> - The second one shows the target window for a bitmap of arbitrary - dimensions [w,h]. - </li> - <li> - The third one shows the juxtaposition of the outline and window in - the 2D plane. - </li> - <li> - The last image shows what will really be rendered in the bitmap. - </li> - </ul> - - <center> - <img src="clipping.png" - height=151 width=539 - alt="clipping algorithm"> - </center> - </ul> - - <p>Indeed, in nearly all cases, the loaded or transformed outline must - be translated before it is rendered into a target bitmap, in order to - adjust its position relative to the target window.</p> - - <p>For example, the correct way of creating a <em>standalone</em> glyph - bitmap is as follows</p> - - <ul> - <li> - <p>Compute the size of the glyph bitmap. It can be computed - directly from the glyph metrics, or by computing its bounding box - (this is useful when a transformation has been applied to the - outline after the load, as the glyph metrics are not valid - anymore).</p> - </li> - <li> - <p>Create the bitmap with the computed dimensions. Don't forget to - fill the pixel buffer with the background color.</p> - </li> - <li> - <p>Translate the outline so that its lower left corner matches - (0,0). Don't forget that in order to preserve hinting, one should - use integer, i.e. rounded distances (of course, this isn't required - if preserving hinting information doesn't matter, like with rotated - text). Usually, this means translating with a vector - <tt>(-ROUND(xMin), -ROUND(yMin))</tt>.</p> - </li> - <li> - <p>Call the rendering function (it can be - <tt>FT_Outline_Render()</tt> for example).</p> - </li> - </ul> - - <p>In the case where one wants to write glyph images directly into a - large bitmap, the outlines must be translated so that their vectorial - position correspond to the current text cursor/character origin.</p> - - <p><hr></p> - - <center> - <table width="100%" - border=0 - cellpadding=5> - <tr bgcolor="#CCFFCC" - valign=center> - <td align=center - width="30%"> - <a href="glyphs-6.html">Previous</a> - </td> - <td align=center - width="30%"> - <a href="index.html">Contents</a> - </td> - <td align=center - width="30%"> - - </td> - </tr> - </table> - </center> - -</td></tr> -</table> -</center> + +<body> + +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> Glyph + Conventions / VII</h1> +</div> + + +<div id="wrapper"> + +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> + + + <!-- ************************************************** --> + + <div id="freetype-bitmaps"> + <h2>VII. FreeType Bitmaps</h2> + + <p>The purpose of this section is to present the way + FreeType manages bitmaps and pixmaps, and how they relate + to the concepts previously defined. The relationship + between vectorial and pixel coordinates is explained.</p> + + + <h3 id="section-1">1. Vectorial versus pixel + coordinates</h3> + + <p>This sub-section explains the difference between + vectorial and pixel coordinates. To make things clear, + brackets will be used to describe pixel coordinates, + e.g. ‘[3,5]’, while parentheses will be used + for vectorial ones, e.g. ‘(-2, 3.5)’.</p> + + <p>In the pixel case, as we use the <em>Y upwards</em> + convention; the coordinate [0, 0] always refers to + the <em>lower left pixel</em> of a bitmap, while + coordinate [width-1, rows-1] to its <em>upper right + pixel</em>.</p> + + <p>In the vectorial case, point coordinates are expressed in + floating units, like (1.25, -2.3). Such a position + doesn't refer to a given pixel, but simply to an + immaterial point in the 2D plane.</p> + + <p>The pixels themselves are indeed <em>square boxes</em> of + the 2D plane, whose centers lie in half pixel coordinates. + For example, the lower left pixel of a bitmap is delimited + by the square (0, 0)-(1, 1), its center being at + location (0.5, 0.5).</p> + + <p>This introduces some differences when computing + distances. For example, the <em>length</em> in pixels of + the line [0, 0]-[10, 0] is 11. However, + the vectorial distance between (0, 0)-(10, 0) + covers exactly 10 pixel centers, hence its length + is 10.</p> + + <p align="center"> + <img src="grid_1.png" + height="390" + width="402" + alt="bitmap and vector grid"> + </p> + + + <h3 id="section-2">2. The <tt>FT_Bitmap</tt> descriptor</h3> + + <p>In FreeType, a bitmap or pixmap is described through a + single structure, + called <a href="../reference/ft2-basic_types.html#FT_Bitmap"><tt>FT_Bitmap</tt></a>. + The fields we are interested in are:</p> + + <table> + <caption> + <b><tt>FT_Bitmap</tt></b> + </caption> + + <tr> + <td valign="top"> + <tt>rows</tt> + </td> + <td valign="top"> + the number of rows, i.e. lines, in the bitmap + </td> + </tr> + <tr> + <td valign="top"> + <tt>width</tt> + </td> + <td valign="top"> + the number of horizontal pixels in the bitmap + </td> + </tr> + <tr> + <td valign="top"> + <tt>pitch</tt> + </td> + <td valign="top"> + its absolute value is the number of bytes per bitmap + line; it can be either positive or negative depending + on the bitmap's vertical orientation + </td> + </tr> + <tr> + <td valign="top"> + <tt>buffer</tt> + </td> + <td valign="top"> + a typeless pointer to the bitmap pixel buffer + </td> + </tr> + <tr> + <td valign="top"> + <tt>pixel_mode</tt> + </td> + <td valign="top"> + an enumeration used to describe the pixel format of + the bitmap; examples are <tt>ft_pixel_mode_mono</tt> + for 1-bit monochrome bitmaps + and <tt>ft_pixel_mode_grays</tt> for 8-bit + anti-aliased ‘gray’ values + </td> + </tr> + <tr> + <td valign="top"> + <tt>num_grays</tt> + </td> + <td valign="top"> + this is only used for ‘gray’ pixel modes, + it gives the number of gray levels used to describe + the anti-aliased gray levels (256 by default with + FreeType 2) + </td> + </tr> + </table> + + <p>Note that the sign of the <tt>pitch</tt> field determines + whether the rows in the pixel buffer are stored in + ascending or descending order.</p> + + <p>Remember that FreeType uses the <em>Y upwards</em> + convention in the 2D plane, which means that a coordinate + of (0, 0) always refer to the <em>lower-left + corner</em> of a bitmap.</p> + + <p>If the pitch is positive, the rows are stored in + decreasing vertical position; the first bytes of the pixel + buffer are part of the <em>upper</em> bitmap row.</p> + + <p>On the opposite, if the pitch is negative, the first + bytes of the pixel buffer are part of the <em>lower</em> + bitmap row.</p> + + <p>In all cases, one can see the pitch as the byte increment + needed to skip to the <em>next lower scanline</em> in a + given bitmap buffer.</p> + + <table> + <tr> + <td> + <img src="up_flow.png" + height="261" + width="275" + alt="negative 'pitch'"> + </td> + <td> + <img src="down_flow.png" + height="263" + width="273" + alt="positive 'pitch'"> + </td> + </tr> + </table> + + <p>The ‘positive pitch’ convention is very often + used, though some systems might need the other.</p> + + + <h3 id="section-3">3. Converting outlines into bitmaps and + pixmaps</h3> + + <p>Generating a bitmap or pixmap image from a vectorial + image is easy with FreeType. However, one must understand + a few points regarding the positioning of the outline in + the 2D plane before converting it to a bitmap:</p> + + <ul> + <li> + <p>The glyph loader and hinter always places the outline + in the 2D plane so that (0, 0) matches its + character origin. This means that the glyph's outline + (and corresponding bounding box), can be placed + anywhere in the 2D plane (see the graphics in + section III).</p> + </li> + <li> + <p>The target bitmap's area is mapped to the 2D plane, + with its lower left corner at (0, 0). This means + that a bitmap or pixmap of dimensions + [<tt>w</tt>, <tt>h</tt>] will be mapped to a 2D + rectangle window delimited by + (0, 0)-(<tt>w</tt>, <tt>h</tt>).</p> + </li> + <li> + <p>When scan-converting the outline, everything that + falls within the bitmap window is rendered, the rest + is ignored.</p> + </li> + + <p>A common mistake made by many developers when they + begin using FreeType is believing that a loaded outline + can be directly rendered in a bitmap of adequate + dimensions. The following images illustrate why this is + a problem.</p> + + <ul> + <li> + The first image shows a loaded outline in the 2D + plane. + </li> + <li> + The second one shows the target window for a bitmap of + arbitrary dimensions [<tt>w</tt>, <tt>h</tt>]. + </li> + <li> + The third one shows the juxtaposition of the outline + and window in the 2D plane. + </li> + <li> + The last image shows what will really be rendered in + the bitmap. + </li> + </ul> + + <p align="center"> + <img src="clipping.png" + height="151" + width="539" + alt="clipping algorithm"> + </p> + </ul> + + <p>Indeed, in nearly all cases, the loaded or transformed + outline must be translated before it is rendered into a + target bitmap, in order to adjust its position relative to + the target window.</p> + + <p>For example, the correct way of creating + a <em>standalone</em> glyph bitmap is as follows:</p> + + <ul> + <li> + <p>Compute the size of the glyph bitmap. It can be + computed directly from the glyph metrics, or by + computing its bounding box (this is useful when a + transformation has been applied to the outline after + loading it, as the glyph metrics are not valid + anymore).</p> + </li> + <li> + <p>Create the bitmap with the computed dimensions. + Don't forget to fill the pixel buffer with the + background color.</p> + </li> + <li> + <p>Translate the outline so that its lower left corner + matches (0, 0). Don't forget that in order to + preserve hinting, one should use integer, i.e., + rounded distances (of course, this isn't required if + preserving hinting information doesn't matter, like + with rotated text). Usually, this means translating + with a vector + (<tt>-ROUND(xMin)</tt>, <tt>-ROUND(yMin)</tt>).</p> + </li> + <li> + <p>Call the rendering function (it can be + <a href="../reference/ft2-outline_processing.html#FT_Outline_Render"><tt>FT_Outline_Render</tt></a>, + for example).</p> + </li> + </ul> + + <p>In the case where one wants to write glyph images + directly into a large bitmap, the outlines must be + translated so that their vectorial position corresponds to + the current text cursor or character origin.</p> + </div> + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 07-Dec-2014</p> + </div> + </div> + </div> + + + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="index.html">FreeType Glyph Conventions</a> + </li> + <li class="tertiary"> + <a href="glyphs-1.html">Basic Typographic Concepts</a> + </li> + <li class="tertiary"> + <a href="glyphs-2.html">Glyph Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-3.html">Glyph Metrics</a> + </li> + <li class="tertiary"> + <a href="glyphs-4.html">Kerning</a> + </li> + <li class="tertiary"> + <a href="glyphs-5.html">Text Processing</a> + </li> + <li class="tertiary"> + <a href="glyphs-6.html">FreeType Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-7.html" class="current">FreeType Bitmaps</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> + +<div id="TOC-bottom"> +</div> </body> </html> diff --git a/lib/freetype/docs/glyphs/index.html b/lib/freetype/docs/glyphs/index.html index 8ee2fa515..c0d4db647 100644 --- a/lib/freetype/docs/glyphs/index.html +++ b/lib/freetype/docs/glyphs/index.html @@ -1,200 +1,289 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en" - "http://www.w3.org/TR/REC-html40/loose.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + <head> <meta http-equiv="Content-Type" - content="text/html; charset=iso-8859-1"> + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> <meta name="Author" content="David Turner"> + + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + <title>FreeType Glyph Conventions</title> </head> -<body text="#000000" - bgcolor="#FFFFFF" - link="#0000EF" - vlink="#51188E" - alink="#FF0000"> - -<h1 align=center> - FreeType Glyph Conventions -</h1> - -<h2 align=center> - Version 2.1 -</h2> - -<h3 align=center> - Copyright 1998-2000 David Turner (<a - href="mailto:david@freetype.org">david@freetype.org</a>)<br> - Copyright 2000 The FreeType Development Team (<a - href="mailto:devel@freetype.org">devel@freetype.org</a>) -</h3> - - -<center> -<table width="70%"> -<tr><td> - - <p>This document presents the core conventions used within the FreeType - library to manage font and glyph data. It is a <em>must-read</em> for all - developers who need to understand digital typography, especially if you - want to use the FreeType 2 library in your projects.</p> - - <table width="100%"> - <tr valign=center - bgcolor="#CCCCFF"> - <td align=center> - <h2> - Table of Contents - </h2> - </td> - </tr> - </table> - - <center> - <table width="80%"> - <tr><td> - - <h2> - <a href="glyphs-1.html">I. Basic Typographic Concepts</a> - </h2> - <blockquote> - <h3> - <a href="glyphs-1.html#section-1">1. Font files, format and - information</a> - <br> - - <a href="glyphs-1.html#section-2">2. Character images and mappings</a> - <br> - - <a href="glyphs-1.html#section-3">3. Character and font metrics</a> - <br> - </h3> - </blockquote> - - <h2> - <a href="glyphs-2.html">II. Glyph outlines</a> - </h2> - <blockquote> - <h3> - <a href="glyphs-2.html#section-1">1. Pixels, points and device - resolutions</a> - <br> - - <a href="glyphs-2.html#section-2">2. Vectorial representation</a> - <br> - - <a href="glyphs-2.html#section-3">3. Hinting and bitmap rendering</a> - <br> - </h3> - </blockquote> - - <h2> - <a href="glyphs-3.html">III. Glyph metrics</a> - </h2> - <blockquote> - <h3> - <a href="glyphs-3.html#section-1">1. Baseline, pens and layouts</a> - <br> - - <a href="glyphs-3.html#section-2">2. Typographic metrics and - bounding boxes</a> - <br> - - <a href="glyphs-3.html#section-3">3. Bearings and advances</a> - <br> - - <a href="glyphs-3.html#section-4">4. The effects of grid-fitting</a> - <br> - - <a href="glyphs-3.html#section-5">5. Text widths and bounding box</a> - <br> - </h3> - </blockquote> - - <h2> - <a href="glyphs-4.html">IV. Kerning</a> - </h2> - <blockquote> - <h3> - <a href="glyphs-4.html#section-1">1. Kerning pairs</a> - <br> - - <a href="glyphs-4.html#section-2">2. Applying kerning</a> - <br> - </h3> - </blockquote> - - <h2> - <a href="glyphs-5.html">V. Text processing</a> - </h2> - <blockquote> - <h3> - <a href="glyphs-5.html#section-1">1. Writing simple text strings</a> - <br> - - <a href="glyphs-5.html#section-2">2. Sub-pixel positioning</a> - <br> - - <a href="glyphs-5.html#section-3">3. Simple kerning</a> - <br> - - <a href="glyphs-5.html#section-4">4. Right-to-left layouts</a> - <br> - - <a href="glyphs-5.html#section-5">5. Vertical layouts</a> - <br> - - <a href="glyphs-5.html#section-6">6. WYSIWYG text layouts</a> - <br> - </h3> - </blockquote> - - <h2> - <a href="glyphs-6.html">VI. FreeType Outlines</a> - </h2> - <blockquote> - <h3> - <a href="glyphs-6.html#section-1">1. FreeType outline description - and structure</a> - <br> - - <a href="glyphs-6.html#section-2">2. Bounding and control box - computations</a> - <br> - - <a href="glyphs-6.html#section-3">3. Coordinates, scaling, and - grid-fitting</a> - <br> - </h3> - </blockquote> - - <h2> - <a href="glyphs-7.html">VII. FreeType bitmaps</a> - </h2> - <blockquote> - <h3> - <a href="glyphs-7.html#section-1">1. Vectorial versus pixel - coordinates</a> - <br> - - <a href="glyphs-7.html#section-2">2. FreeType bitmap and pixmap - descriptor</a> - <br> - - <a href="glyphs-7.html#section-3">3. Converting outlines into - bitmaps and pixmaps</a> - <br> - </h3> - </blockquote> - - </td></tr> - </table> - </center> - -</td></tr> -</table> -</center> + +<body> + +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> Glyph Conventions</h1> +</div> + + +<div id="wrapper"> + +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> + + + <!-- ************************************************** --> + + <div id="introduction"> + <p>This document presents the core conventions used within + the FreeType library to manage font and glyph data. It is + a <em>must-read</em> for all developers who need to + understand digital typography, especially if you want to + use the FreeType 2 library in your projects.</p> + </div> + + <!-- ************************************************** --> + + <div id="contents"> + <h3><a href="glyphs-1.html">I. Basic Typographic + Concepts</a></h3> + <ul> + <li> + <a href="glyphs-1.html#section-1">1. Font files, format + and information</a> + </li> + <li> + <a href="glyphs-1.html#section-2">2. Character images + and mappings</a> + </li> + <li> + <a href="glyphs-1.html#section-3">3. Character and font + metrics</a> + </li> + </ul> + + <h3><a href="glyphs-2.html">II. Glyph Outlines</a></h3> + <ul> + <li> + <a href="glyphs-2.html#section-1">1. Pixels, points and + device resolutions</a> + </li> + <li> + <a href="glyphs-2.html#section-2">2. Vectorial + representation</a> + </li> + <li> + <a href="glyphs-2.html#section-3">3. Hinting and bitmap + rendering</a> + </li> + </ul> + + <h3><a href="glyphs-3.html">III. Glyph Metrics</a></h3> + <ul> + <li> + <a href="glyphs-3.html#section-1">1. Baseline, pens and + layouts</a> + </li> + <li> + <a href="glyphs-3.html#section-2">2. Typographic metrics + and bounding boxes</a> + </li> + <li> + <a href="glyphs-3.html#section-3">3. Bearings and + advances</a> + </li> + <li> + <a href="glyphs-3.html#section-4">4. The effects of + grid-fitting</a> + </li> + <li> + <a href="glyphs-3.html#section-5">5. Text widths and + bounding box</a> + </li> + </ul> + + <h3><a href="glyphs-4.html">IV. Kerning</a></h3> + <ul> + <li> + <a href="glyphs-4.html#section-1">1. Kerning pairs</a> + </li> + <li> + <a href="glyphs-4.html#section-2">2. Applying + kerning</a> + </li> + </ul> + + <h3><a href="glyphs-5.html">V. Text Processing</a></h3> + <ul> + <li> + <a href="glyphs-5.html#section-1">1. Writing simple text + strings</a> + </li> + <li> + <a href="glyphs-5.html#section-2">2. Sub-pixel + positioning</a> + </li> + <li> + <a href="glyphs-5.html#section-3">3. Simple kerning</a> + </li> + <li> + <a href="glyphs-5.html#section-4">4. Right-to-left + layouts</a> + </li> + <li> + <a href="glyphs-5.html#section-5">5. Vertical + layouts</a> + </li> + </ul> + + <h3><a href="glyphs-6.html">VI. FreeType Outlines</a></h3> + <ul> + <li> + <a href="glyphs-6.html#section-1">1. FreeType outline + description and structure</a> + </li> + <li> + <a href="glyphs-6.html#section-2">2. Bounding and + control box computations</a> + </li> + <li> + <a href="glyphs-6.html#section-3">3. Coordinates, + scaling, and grid-fitting</a> + </li> + </ul> + + <h3><a href="glyphs-7.html">VII. FreeType Bitmaps</a></h3> + <ul> + <li> + <a href="glyphs-7.html#section-1">1. Vectorial versus + pixel coordinates</a> + </li> + <li> + <a href="glyphs-7.html#section-2">2. The <tt>FT_Bitmap</tt> + descriptor</a> + </li> + <li> + <a href="glyphs-7.html#section-3">3. Converting outlines + into bitmaps and pixmaps</a> + </li> + </ul> + </div> + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 07-Dec-2014</p> + </div> + </div> + </div> + + + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="glyphs-1.html" class="current">FreeType Glyph Conventions</a> + </li> + <li class="tertiary"> + <a href="glyphs-1.html">Basic Typographic Concepts</a> + </li> + <li class="tertiary"> + <a href="glyphs-2.html">Glyph Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-3.html">Glyph Metrics</a> + </li> + <li class="tertiary"> + <a href="glyphs-4.html">Kerning</a> + </li> + <li class="tertiary"> + <a href="glyphs-5.html">Text Processing</a> + </li> + <li class="tertiary"> + <a href="glyphs-6.html">FreeType Outlines</a> + </li> + <li class="tertiary"> + <a href="glyphs-7.html">FreeType Bitmaps</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> + +<div id="TOC-bottom"> +</div> </body> </html> diff --git a/lib/freetype/docs/image/favicon.ico b/lib/freetype/docs/image/favicon.ico Binary files differnew file mode 100644 index 000000000..72a53b6a6 --- /dev/null +++ b/lib/freetype/docs/image/favicon.ico diff --git a/lib/freetype/docs/image/favicon_-30.ico b/lib/freetype/docs/image/favicon_-30.ico Binary files differnew file mode 100644 index 000000000..c695f0f29 --- /dev/null +++ b/lib/freetype/docs/image/favicon_-30.ico diff --git a/lib/freetype/docs/image/favicon_-60.ico b/lib/freetype/docs/image/favicon_-60.ico Binary files differnew file mode 100644 index 000000000..a1a22ed43 --- /dev/null +++ b/lib/freetype/docs/image/favicon_-60.ico diff --git a/lib/freetype/docs/image/favicon_-90.ico b/lib/freetype/docs/image/favicon_-90.ico Binary files differnew file mode 100644 index 000000000..201ec2274 --- /dev/null +++ b/lib/freetype/docs/image/favicon_-90.ico diff --git a/lib/freetype/docs/image/favicon_30.ico b/lib/freetype/docs/image/favicon_30.ico Binary files differnew file mode 100644 index 000000000..3f719d1ea --- /dev/null +++ b/lib/freetype/docs/image/favicon_30.ico diff --git a/lib/freetype/docs/image/favicon_60.ico b/lib/freetype/docs/image/favicon_60.ico Binary files differnew file mode 100644 index 000000000..6f5622114 --- /dev/null +++ b/lib/freetype/docs/image/favicon_60.ico diff --git a/lib/freetype/docs/image/favicon_90.ico b/lib/freetype/docs/image/favicon_90.ico Binary files differnew file mode 100644 index 000000000..b5886effe --- /dev/null +++ b/lib/freetype/docs/image/favicon_90.ico diff --git a/lib/freetype/docs/image/fond2-small.png b/lib/freetype/docs/image/fond2-small.png Binary files differnew file mode 100644 index 000000000..44144682b --- /dev/null +++ b/lib/freetype/docs/image/fond2-small.png diff --git a/lib/freetype/docs/image/fond2.png b/lib/freetype/docs/image/fond2.png Binary files differnew file mode 100644 index 000000000..214d7d9df --- /dev/null +++ b/lib/freetype/docs/image/fond2.png diff --git a/lib/freetype/docs/image/fond3.jpg b/lib/freetype/docs/image/fond3.jpg Binary files differnew file mode 100644 index 000000000..dfb732738 --- /dev/null +++ b/lib/freetype/docs/image/fond3.jpg diff --git a/lib/freetype/docs/image/fond3.png b/lib/freetype/docs/image/fond3.png Binary files differnew file mode 100644 index 000000000..fdebb227e --- /dev/null +++ b/lib/freetype/docs/image/fond3.png diff --git a/lib/freetype/docs/image/fond3_-30.png b/lib/freetype/docs/image/fond3_-30.png Binary files differnew file mode 100644 index 000000000..f6c655739 --- /dev/null +++ b/lib/freetype/docs/image/fond3_-30.png diff --git a/lib/freetype/docs/image/fond3_-60.png b/lib/freetype/docs/image/fond3_-60.png Binary files differnew file mode 100644 index 000000000..3771205b7 --- /dev/null +++ b/lib/freetype/docs/image/fond3_-60.png diff --git a/lib/freetype/docs/image/fond3_-90.png b/lib/freetype/docs/image/fond3_-90.png Binary files differnew file mode 100644 index 000000000..8ff9d6050 --- /dev/null +++ b/lib/freetype/docs/image/fond3_-90.png diff --git a/lib/freetype/docs/image/fond3_30.png b/lib/freetype/docs/image/fond3_30.png Binary files differnew file mode 100644 index 000000000..372155a69 --- /dev/null +++ b/lib/freetype/docs/image/fond3_30.png diff --git a/lib/freetype/docs/image/fond3_60.png b/lib/freetype/docs/image/fond3_60.png Binary files differnew file mode 100644 index 000000000..f78c25108 --- /dev/null +++ b/lib/freetype/docs/image/fond3_60.png diff --git a/lib/freetype/docs/image/fond3_90.png b/lib/freetype/docs/image/fond3_90.png Binary files differnew file mode 100644 index 000000000..11374aaa4 --- /dev/null +++ b/lib/freetype/docs/image/fond3_90.png diff --git a/lib/freetype/docs/image/freetype.jpg b/lib/freetype/docs/image/freetype.jpg Binary files differnew file mode 100644 index 000000000..0c6304fa1 --- /dev/null +++ b/lib/freetype/docs/image/freetype.jpg diff --git a/lib/freetype/docs/image/top.gif b/lib/freetype/docs/image/top.gif Binary files differnew file mode 100644 index 000000000..6ed55656a --- /dev/null +++ b/lib/freetype/docs/image/top.gif diff --git a/lib/freetype/docs/index.html b/lib/freetype/docs/index.html new file mode 100644 index 000000000..a89262685 --- /dev/null +++ b/lib/freetype/docs/index.html @@ -0,0 +1,330 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Overview"> + + <link rel="icon" + href="image/favicon_-60.ico"> + <link rel="shortcut icon" + href="image/favicon_-60.ico"> + <link rel="stylesheet" + type="text/css" + href="css/freetype2_-60.css"> + + <script type="text/javascript" + src="javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="javascript/freetype2.js"> + </script> + + <title>FreeType Overview</title> +</head> + + +<body> + +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> Overview</h1> +</div> + + +<div id="wrapper"> + +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> + + + <!-- ************************************************** --> + + <div id="what-is-freetype"> + <h2>What is FreeType?</h2> + + <p>FreeType is a software font engine that is designed to + be small, efficient, highly customizable, and portable + while capable of producing high-quality output (glyph + images). It can be used in graphics libraries, display + servers, font conversion tools, text image generation + tools, and many other products as well.</p> + + <p>Note that FreeType is a <em>font service</em> and doesn't + provide APIs to perform higher-level features like text + layout or graphics processing (e.g., colored text + rendering, ‘hollowing’, etc.). However, it + greatly simplifies these tasks by providing a simple, easy + to use, and uniform interface to access the content of + font files.</p> + + <p>FreeType is released under two open-source licenses: our + own + BSD-like <a href="http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/FTL.TXT">FreeType + License</a> and + the <a href="http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/GPLv2.TXT">GNU + Public License, Version 2</a>. It can thus be used + by any kind of projects, be they proprietary or not.</p> + + <p>Please note that ‘FreeType’ is also called + ‘FreeType 2’, to distinguish it from the + old, deprecated ‘FreeType 1’ library, a + predecessor no longer maintained and supported.</p> + </div> + + + <!-- ************************************************** --> + + <div id="features"> + <h2>Features</h2> + + <p>The following is a non-exhaustive list of features + provided by FreeType.</p> + + <ul> + <li> + <p>FreeType provides a simple and easy-to-use API to + access font content in a uniform way, independently of + the file format. Additionally, some format-specific + APIs can be used to access special data in the font + file.</p> + </li> + <li> + <p>The design of FreeType is based on modules that can + be either linked statically to the library at compile + time, or loaded on demand at runtime. Modules are + used to support specific font formats, or even new + glyph image formats!</p> + </li> + <li> + <p>FreeType was written with embedded systems in mind. + This means that it doesn't use static writable data + (i.e., it can be run from ROM directly), and that + client applications can provide their own memory + manager and I/O stream implementation. The latter + allows you to easily read from ROM-based, compressed + or remote font files with the same API. Several + stream implementations can be used concurrently with a + single FreeType instance.</p> + + <p>You can also reduce the size of the FreeType code by + only compiling the modules you need for your embedded + project or environment.</p> + </li> + <li> + <p>By default, FreeType supports the following font + formats.</p> + + <ul> + <li>TrueType fonts (TTF) and TrueType collections + (TTC)</li> + <li>CFF fonts</li> + <li>WOFF fonts</li> + <li>OpenType fonts (OTF, both TrueType and CFF + variants) and OpenType collections (OTC)</li> + <li>Type 1 fonts (PFA and PFB)</li> + <li>CID-keyed Type 1 fonts</li> + <li>SFNT-based bitmap fonts, including color Emoji</li> + <li>X11 PCF fonts</li> + <li>Windows FNT fonts</li> + <li>BDF fonts (including anti-aliased ones)</li> + <li>PFR fonts</li> + <li>Type 42 fonts (limited support)</li> + </ul> + </li> + <li> + <p>From a given glyph outline, FreeType is capable of + producing a high-quality monochrome bitmap, or + anti-aliased pixmap, using 256 levels of + ‘gray’.</p> + </li> + <li> + <p>FreeType supports all the character mappings defined + by the TrueType and OpenType specifications. It is + also capable of automatically synthetizing a Unicode + charmap from Type 1 fonts, avoiding painful + ‘encoding translation’ problems common + with this format (of course, original encodings are + also available if necessary).</p> + </li> + <li> + <p>The FreeType core API provides simple functions to + access advanced information like glyph names or basic + kerning data.</p> + </li> + <li> + <p>A full-featured and efficient TrueType bytecode + interpreter, trying to match the results of the + Windows bytecode engine. There is also the + possibility to activate subpixel hinting + (a.k.a. <em>ClearType</em>, still under + development).</p> + </li> + <li> + <p>For those who don't need or want to use the bytecode + interpreter for TrueType fonts, we developed our + own <em>automatic hinter</em> module. It is also used + by other scalable formats.</p> + </li> + <li> + <p>Due to its modular design, it is easy to enhance the + library, providing additional format-specific + information through optional APIs (as an example, an + optional API is provided to retrieve SFNT tables from + TrueType and OpenType fonts).</p> + </li> + <li> + <p>FreeType provides its own caching subsystem. It can + be used to cache either face instances or glyph images + efficiently.</p> + </li> + <li> + <p>A bundle of demo programs demonstrate the usage of + FreeType; look for the + ‘ft2demos-<i>x.x.x</i>’ archive (or + ‘ftdmo<i>xxx</i>’ in case you are on a + Windows platform) at the locations + given <a href="http://freetype.org/download.html">here</a>. + ‘<i>x.x.x</i>’ (or + ‘<i>xxx</i>’) gives the version number, + for example ‘2.4.10’ or + ‘2410’.</p> + </li> + </ul> + </div> + + + <!-- ************************************************** --> + + <div id="requirements"> + <h2>Requirements</h2> + + <p>FreeType is written in industry-standard ANSI C and + should compile easily with any compliant C or C++ + compiler. We have even taken great care to + eliminate <em>all warnings</em> when compiling with + popular compilers like gcc, Visual C++, and Borland + C++.</p> + + <p>Apart from a standard ANSI C library, FreeType + doesn't have any external dependencies and can be compiled + and installed on its own on any kind of system. Some + modules <em>need</em> external libraries (e.g., for + handling fonts compressed with gzip or bz2), however, they + are optional and can be disabled.</p> + </div> + + + <!-- ************************************************** --> + + <div id="patents"> + <h2>Patent Issues</h2> + + <p>All patents related to the TrueType bytecode interpreter + have expired since May 2010. Support for the still + patented ClearType color filtering model is disabled by + default.</p> + + <p>More information regarding this topic is available at + our <a href="http://freetype.org/patents.html">patents page</a>.</p> + </div> + + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 7-Dec-2014</p> + </div> + </div> + </div> + + + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="index.html" class="current">Overview</a> + </li> + <li class="primary"> + <a href="documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="#what-is-freetype">What is FreeType?</a> + </li> + <li class="secondary"> + <a href="#features">Features</a> + </li> + <li class="secondary"> + <a href="#requirements">Requirements</a> + </li> + <li class="secondary"> + <a href="#patents">Patents</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> + +<div id="TOC-bottom"> +</div> + +</body> +</html> diff --git a/lib/freetype/docs/javascript/freetype2.js b/lib/freetype/docs/javascript/freetype2.js new file mode 100644 index 000000000..0a15a21dd --- /dev/null +++ b/lib/freetype/docs/javascript/freetype2.js @@ -0,0 +1,78 @@ +/*! + * freetype2.js + * + * auxiliary JavaScript functions for freetype.org + * + * written 2012 by Werner Lemberg + */ + +// This code snippet needs `jquery' +// (http://code.jquery.com/jquery-1.8.3.js) and `jquery-resize' +// (http://github.com/cowboy/jquery-resize/raw/master/jquery.ba-resize.js) + + +// Add a bottom bar if the document length exceeds the window height. +// Additionally ensure that the TOC background reaches the bottom of the +// window. + +function addBottomBar() { + var columnHeight = $('.colright').height(); + var topBarHeight = $('#top').height(); + var winHeight = $(window).height(); + + if (columnHeight + topBarHeight > winHeight) { + $('#TOC-bottom').css('height', columnHeight); + /* add bottom bar if it doesn't exist already */ + if ($('#bottom').length == 0) { + $('body').append('<div class="bar" id="bottom"></div>'); + } + } + else { + $('#TOC-bottom').css('height', winHeight - topBarHeight); + $('#bottom').remove(); + } +} + + +// `Slightly' scroll the TOC so that its top moves up to the top of the +// screen if we scroll down. The function also assures that the bottom of +// the TOC doesn't cover the bottom bar (e.g., if the window height is very +// small). + +function adjustTOCPosition() { + var docHeight = $(document).height(); + var TOCHeight = $('#TOC').height(); + var bottomBarHeight = $('#bottom').height(); + var topBarHeight = $('#top').height(); + + var scrollTopPos = $(window).scrollTop(); + var topBarBottomPos = 0 + topBarHeight; + var bottomBarTopPos = docHeight - bottomBarHeight; + + if (scrollTopPos >= topBarBottomPos) { + $('#TOC').css('top', 0); + } + if (scrollTopPos < topBarBottomPos) { + $('#TOC').css('top', topBarBottomPos - scrollTopPos); + } + if (bottomBarTopPos - scrollTopPos < TOCHeight) + $('#TOC').css('top', bottomBarTopPos - scrollTopPos - TOCHeight); +} + + +// Hook functions into loading, resizing, and scrolling events. + +$(window).load(function() { + addBottomBar(); + adjustTOCPosition(); + + $(window).scroll(function() { + adjustTOCPosition(); + }); + + $('#TOC-bottom').add(window).resize(function() { + addBottomBar(); + }); +}); + +/* end of freetype2.js */ diff --git a/lib/freetype/docs/javascript/jquery-1.11.0.min.js b/lib/freetype/docs/javascript/jquery-1.11.0.min.js new file mode 100644 index 000000000..73f33fb3a --- /dev/null +++ b/lib/freetype/docs/javascript/jquery-1.11.0.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f +}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},W=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a>",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=$.test(e)?this.mouseHooks:Z.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||z),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||z,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==db()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===db()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=z.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===L&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&(a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault())?bb:cb):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:cb,isPropagationStopped:cb,isImmediatePropagationStopped:cb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=bb,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=bb,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submitBubbles||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?b.form:void 0;c&&!n._data(c,"submitBubbles")&&(n.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),n._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.changeBubbles||(n.event.special.change={setup:function(){return Y.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),n.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),n.event.simulate("change",this,a,!0)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;Y.test(b.nodeName)&&!n._data(b,"changeBubbles")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a,!0)}),n._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!Y.test(this.nodeName)}}),l.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=cb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return n().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=cb),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});function eb(a){var b=fb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var fb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gb=/ jQuery\d+="(?:null|\d+)"/g,hb=new RegExp("<(?:"+fb+")[\\s/>]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/<tbody/i,mb=/<|&#?\w+;/,nb=/<(?:script|style|link)/i,ob=/checked\s*(?:[^=]|=\s*.checked.)/i,pb=/^$|\/(?:java|ecma)script/i,qb=/^true\/(.*)/,rb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,sb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1></$2>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?"<table>"!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Db[0].contentWindow||Db[0].contentDocument).document,b.write(),b.close(),c=Fb(a,b),Db.detach()),Eb[a]=c),c}!function(){var a,b,c=z.createElement("div"),d="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],a.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(a.style.opacity),l.cssFloat=!!a.style.cssFloat,c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===c.style.backgroundClip,a=c=null,l.shrinkWrapBlocks=function(){var a,c,e,f;if(null==b){if(a=z.getElementsByTagName("body")[0],!a)return;f="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",c=z.createElement("div"),e=z.createElement("div"),a.appendChild(c).appendChild(e),b=!1,typeof e.style.zoom!==L&&(e.style.cssText=d+";width:1px;padding:1px;zoom:1",e.innerHTML="<div></div>",e.firstChild.style.width="5px",b=3!==e.offsetWidth),a.removeChild(c),a=c=e=null}return b}}();var Hb=/^margin/,Ib=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Jb,Kb,Lb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Jb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),Ib.test(g)&&Hb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):z.documentElement.currentStyle&&(Jb=function(a){return a.currentStyle},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ib.test(g)&&!Lb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Mb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h=z.createElement("div"),i="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",j="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";h.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",b=h.getElementsByTagName("a")[0],b.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(b.style.opacity),l.cssFloat=!!b.style.cssFloat,h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,b=h=null,n.extend(l,{reliableHiddenOffsets:function(){if(null!=c)return c;var a,b,d,e=z.createElement("div"),f=z.getElementsByTagName("body")[0];if(f)return e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=z.createElement("div"),a.style.cssText=i,f.appendChild(a).appendChild(e),e.innerHTML="<table><tr><td></td><td>t</td></tr></table>",b=e.getElementsByTagName("td"),b[0].style.cssText="padding:0;margin:0;border:0;display:none",d=0===b[0].offsetHeight,b[0].style.display="",b[1].style.display="none",c=d&&0===b[0].offsetHeight,f.removeChild(a),e=f=null,c},boxSizing:function(){return null==d&&k(),d},boxSizingReliable:function(){return null==e&&k(),e},pixelPosition:function(){return null==f&&k(),f},reliableMarginRight:function(){var b,c,d,e;if(null==g&&a.getComputedStyle){if(b=z.getElementsByTagName("body")[0],!b)return;c=z.createElement("div"),d=z.createElement("div"),c.style.cssText=i,b.appendChild(c).appendChild(d),e=d.appendChild(z.createElement("div")),e.style.cssText=d.style.cssText=j,e.style.marginRight=e.style.width="0",d.style.width="1px",g=!parseFloat((a.getComputedStyle(e,null)||{}).marginRight),b.removeChild(c)}return g}});function k(){var b,c,h=z.getElementsByTagName("body")[0];h&&(b=z.createElement("div"),c=z.createElement("div"),b.style.cssText=i,h.appendChild(b).appendChild(c),c.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%",n.swap(h,null!=h.style.zoom?{zoom:1}:{},function(){d=4===c.offsetWidth}),e=!0,f=!1,g=!0,a.getComputedStyle&&(f="1%"!==(a.getComputedStyle(c,null)||{}).top,e="4px"===(a.getComputedStyle(c,null)||{width:"4px"}).width),h.removeChild(b),c=h=null)}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Nb=/alpha\([^)]*\)/i,Ob=/opacity\s*=\s*([^)]*)/,Pb=/^(none|table(?!-c[ea]).+)/,Qb=new RegExp("^("+T+")(.*)$","i"),Rb=new RegExp("^([+-])=("+T+")","i"),Sb={position:"absolute",visibility:"hidden",display:"block"},Tb={letterSpacing:0,fontWeight:400},Ub=["Webkit","O","Moz","ms"];function Vb(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ub.length;while(e--)if(b=Ub[e]+c,b in a)return b;return d}function Wb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=n._data(d,"olddisplay",Gb(d.nodeName)))):f[g]||(e=V(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Xb(a,b,c){var d=Qb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Yb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Zb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Jb(a),g=l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Kb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ib.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Yb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Kb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=Vb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Rb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]="",i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Vb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Kb(a,b,d)),"normal"===f&&b in Tb&&(f=Tb[b]),""===c||c?(e=parseFloat(f),c===!0||n.isNumeric(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&Pb.test(n.css(a,"display"))?n.swap(a,Sb,function(){return Zb(a,b,d)}):Zb(a,b,d):void 0},set:function(a,c,d){var e=d&&Jb(a);return Xb(a,c,d?Yb(a,b,d,l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Ob.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Nb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Nb.test(f)?f.replace(Nb,e):f+" "+e)}}),n.cssHooks.marginRight=Mb(l.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},Kb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Hb.test(a)||(n.cssHooks[a+b].set=Xb)}),n.fn.extend({css:function(a,b){return W(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Jb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b) +},a,b,arguments.length>1)},show:function(){return Wb(this,!0)},hide:function(){return Wb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function $b(a,b,c,d,e){return new $b.prototype.init(a,b,c,d,e)}n.Tween=$b,$b.prototype={constructor:$b,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=$b.propHooks[this.prop];return a&&a.get?a.get(this):$b.propHooks._default.get(this)},run:function(a){var b,c=$b.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):$b.propHooks._default.set(this),this}},$b.prototype.init.prototype=$b.prototype,$b.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},$b.propHooks.scrollTop=$b.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=$b.prototype.init,n.fx.step={};var _b,ac,bc=/^(?:toggle|show|hide)$/,cc=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),dc=/queueHooks$/,ec=[jc],fc={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=cc.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&cc.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function gc(){return setTimeout(function(){_b=void 0}),_b=n.now()}function hc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=U[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function ic(a,b,c){for(var d,e=(fc[b]||[]).concat(fc["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function jc(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&V(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k=Gb(a.nodeName),"none"===j&&(j=k),"inline"===j&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==k?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],bc.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}if(!n.isEmptyObject(o)){r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=ic(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function kc(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function lc(a,b,c){var d,e,f=0,g=ec.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=_b||gc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:_b||gc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(kc(k,j.opts.specialEasing);g>f;f++)if(d=ec[f].call(j,a,k,j.opts))return d;return n.map(k,ic,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(lc,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],fc[c]=fc[c]||[],fc[c].unshift(b)},prefilter:function(a,b){b?ec.unshift(a):ec.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=lc(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&dc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(hc(b,!0),a,d,e)}}),n.each({slideDown:hc("show"),slideUp:hc("hide"),slideToggle:hc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(_b=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),_b=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ac||(ac=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(ac),ac=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e=z.createElement("div");e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=e.getElementsByTagName("a")[0],c=z.createElement("select"),d=c.appendChild(z.createElement("option")),b=e.getElementsByTagName("input")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==e.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=d.selected,l.enctype=!!z.createElement("form").enctype,c.disabled=!0,l.optDisabled=!d.disabled,b=z.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value,a=b=c=d=e=null}();var mc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(mc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.text(a)}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var nc,oc,pc=n.expr.attrHandle,qc=/^(?:checked|selected)$/i,rc=l.getSetAttribute,sc=l.input;n.fn.extend({attr:function(a,b){return W(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===L?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?oc:nc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(F);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?sc&&rc||!qc.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(rc?c:d)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),oc={set:function(a,b,c){return b===!1?n.removeAttr(a,c):sc&&rc||!qc.test(c)?a.setAttribute(!rc&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=pc[b]||n.find.attr;pc[b]=sc&&rc||!qc.test(b)?function(a,b,d){var e,f;return d||(f=pc[b],pc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,pc[b]=f),e}:function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),sc&&rc||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):nc&&nc.set(a,b,c)}}),rc||(nc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},pc.id=pc.name=pc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:nc.set},n.attrHooks.contenteditable={set:function(a,b,c){nc.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var tc=/^(?:input|select|textarea|button|object)$/i,uc=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return W(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):tc.test(a.nodeName)||uc.test(a.nodeName)&&a.href?0:-1}}}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var vc=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(F)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===L||"boolean"===c)&&(this.className&&n._data(this,"__className__",this.className),this.className=this.className||a===!1?"":n._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(vc," ").indexOf(b)>=0)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var wc=n.now(),xc=/\?/,yc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(yc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var zc,Ac,Bc=/#.*$/,Cc=/([?&])_=[^&]*/,Dc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Ec=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Fc=/^(?:GET|HEAD)$/,Gc=/^\/\//,Hc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ic={},Jc={},Kc="*/".concat("*");try{Ac=location.href}catch(Lc){Ac=z.createElement("a"),Ac.href="",Ac=Ac.href}zc=Hc.exec(Ac.toLowerCase())||[];function Mc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(F)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nc(a,b,c,d){var e={},f=a===Jc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Oc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Pc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Qc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ac,type:"GET",isLocal:Ec.test(zc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Oc(Oc(a,n.ajaxSettings),b):Oc(n.ajaxSettings,a)},ajaxPrefilter:Mc(Ic),ajaxTransport:Mc(Jc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Dc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||Ac)+"").replace(Bc,"").replace(Gc,zc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(F)||[""],null==k.crossDomain&&(c=Hc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===zc[1]&&c[2]===zc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(zc[3]||("http:"===zc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),Nc(Ic,k,b,v),2===t)return v;h=k.global,h&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Fc.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(xc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Cc.test(e)?e.replace(Cc,"$1_="+wc++):e+(xc.test(e)?"&":"?")+"_="+wc++)),k.ifModified&&(n.lastModified[e]&&v.setRequestHeader("If-Modified-Since",n.lastModified[e]),n.etag[e]&&v.setRequestHeader("If-None-Match",n.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Kc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Nc(Jc,k,b,v)){v.readyState=1,h&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Pc(k,v,c)),u=Qc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(n.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!l.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||n.css(a,"display"))},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var Rc=/%20/g,Sc=/\[\]$/,Tc=/\r?\n/g,Uc=/^(?:submit|button|image|reset|file)$/i,Vc=/^(?:input|select|textarea|keygen)/i;function Wc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Sc.test(a)?d(a,e):Wc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Wc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Wc(c,a[c],b,e);return d.join("&").replace(Rc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Vc.test(this.nodeName)&&!Uc.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Tc,"\r\n")}}):{name:b.name,value:c.replace(Tc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&$c()||_c()}:$c;var Xc=0,Yc={},Zc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Yc)Yc[a](void 0,!0)}),l.cors=!!Zc&&"withCredentials"in Zc,Zc=l.ajax=!!Zc,Zc&&n.ajaxTransport(function(a){if(!a.crossDomain||l.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Xc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Yc[g],b=void 0,f.onreadystatechange=n.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Yc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function $c(){try{return new a.XMLHttpRequest}catch(b){}}function _c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=z.head||n("head")[0]||z.documentElement;return{send:function(d,e){b=z.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var ad=[],bd=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=ad.pop()||n.expando+"_"+wc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(bd.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&bd.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(bd,"$1"+e):b.jsonp!==!1&&(b.url+=(xc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,ad.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||z;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var cd=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&cd)return cd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h,a.length),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&n.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var dd=a.document.documentElement;function ed(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(typeof e.getBoundingClientRect!==L&&(d=e.getBoundingClientRect()),c=ed(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||dd;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||dd})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return W(this,function(a,d,e){var f=ed(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Mb(l.pixelPosition,function(a,c){return c?(c=Kb(a,b),Ib.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return W(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var fd=a.jQuery,gd=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=gd),b&&a.jQuery===n&&(a.jQuery=fd),n},typeof b===L&&(a.jQuery=a.$=n),n}); diff --git a/lib/freetype/docs/javascript/jquery.ba-resize.min.js b/lib/freetype/docs/javascript/jquery.ba-resize.min.js new file mode 100644 index 000000000..c67888314 --- /dev/null +++ b/lib/freetype/docs/javascript/jquery.ba-resize.min.js @@ -0,0 +1,9 @@ +/* + * jQuery resize event - v1.1 - 3/14/2010 + * http://benalman.com/projects/jquery-resize-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
\ No newline at end of file diff --git a/lib/freetype/docs/tutorial/index.html b/lib/freetype/docs/tutorial/index.html new file mode 100644 index 000000000..ce1adcf89 --- /dev/null +++ b/lib/freetype/docs/tutorial/index.html @@ -0,0 +1,215 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> + <meta name="Author" + content="David Turner"> + + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + + <title>FreeType Tutorial</title> +</head> + + +<body> + +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> Tutorial</h1> +</div> + + +<div id="wrapper"> + +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> + + + <!-- ************************************************** --> + + <div id="introduction"> + <p>This tutorial presents a step-by-step introduction into + the FreeType library, covering the most basic needs.</p> + </div> + + <!-- ************************************************** --> + + <div id="contents"> + <h3><a href="step1.html">I. Simple Glyph Loading</a></h3> + <ul> + <li> + <a href="step1.html#section-1">1. Header Files</a> + </li> + <li> + <a href="step1.html#section-2">2. Library + Initialization</a> + </li> + <li> + <a href="step1.html#section-3">3. Loading a Font + Face</a> + </li> + <li> + <a href="step1.html#section-4">4. Accessing the Face + Data</a> + </li> + <li> + <a href="step1.html#section-5">5. Setting the Current + Pixel Size</a> + </li> + <li> + <a href="step1.html#section-6">6. Loading a Glyph + Image</a> + </li> + <li> + <a href="step1.html#section-7">7. Simple Text + Rendering</a> + </li> + </ul> + + <h3><a href="step2.html">II. Managing Glyphs</a></h3> + <ul> + <li> + <a href="step2.html#section-1">1. Glyph Metrics</a> + </li> + <li> + <a href="step2.html#section-2">2. Managing Glyph + Images</a> + </li> + <li> + <a href="step2.html#section-3">3. Global Glyph + Metrics</a> + </li> + <li> + <a href="step2.html#section-4">4. Simple Text Rendering: + Kerning and Centering</a> + </li> + <li> + <a href="step2.html#section-5">5. Advanced Text + Rendering: Transformation and Centering and + Kerning</a> + </li> + <li> + <a href="step2.html#section-6">6. Accessing Metrics in + Design Font Units, and Scaling Them</a> + </li> + <li> + <a href="step2.html#conclusion">Conclusion</a> + </li> + </ul> + + <h3><a href="step3.html">III. Examples</a></h3> + </div> + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 7-Dec-2014</p> + </div> + </div> + </div> + + + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="index.html" class="current">FreeType Tutorial</a> + </li> + <li class="tertiary"> + <a href="step1.html">Simple Glyph Loading</a> + </li> + <li class="tertiary"> + <a href="step2.html">Managing Glyphs</a> + </li> + <li class="tertiary"> + <a href="step3.html">Examples</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> + +<div id="TOC-bottom"> +</div> + +</body> +</html> diff --git a/lib/freetype/docs/tutorial/step1.html b/lib/freetype/docs/tutorial/step1.html index 3709f6d18..17490ce94 100644 --- a/lib/freetype/docs/tutorial/step1.html +++ b/lib/freetype/docs/tutorial/step1.html @@ -1,1106 +1,1055 @@ -<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" -"http://www.w3.org/TR/html4/loose.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + <head> - <style type="text/css"> - body { font-family: Verdana, Geneva, Arial, Helvetica, serif; - color: #000000; - background: #FFFFFF; } - - p { text-align: justify; } - h1 { text-align: center; } - li { text-align: justify; } - td { padding: 0 0.5em 0 0.5em; } - - a:link { color: #0000EF; } - a:visited { color: #51188E; } - a:hover { color: #FF0000; } - - div.pre { font-family: monospace; - text-align: left; - white-space: pre; - color: blue; } - - span.comment { color: gray; } - </style> <meta http-equiv="Content-Type" - content="text/html; charset=iso-8859-1"> + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> <meta name="Author" content="David Turner"> - <title>FreeType 2 Tutorial</title> -</head> - -<body text="#000000" - bgcolor="#FFFFFF" - link="#0000EF" - vlink="#51188E" - alink="#FF0000"> -<h1 align=center> - FreeType 2 Tutorial<br> - Step 1 — simple glyph loading -</h1> - -<h3 align=center> - © 2003, 2006, 2007, 2009, 2010 David Turner - (<a href="mailto:david@freetype.org">david@freetype.org</a>)<br> - © 2003, 2006, 2007, 2009, 2010 The FreeType Development Team - (<a href="http://www.freetype.org">www.freetype.org</a>) -</h3> + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + + <title>FreeType Tutorial / I</title> +</head> -<center> -<table width="70%"> -<tr><td> - <hr> +<body> - <h2> - Introduction - </h2> +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> + Tutorial / I</h1> +</div> - <p>This is the first section of the FreeType 2 tutorial. It will teach - you how to:</p> - <ul> - <li>initialize the library</li> - <li>open a font file by creating a new face object</li> - <li>select a character size in points or in pixels</li> - <li>load a single glyph image and convert it to a bitmap</li> - <li>render a very simple string of text</li> - <li>render a rotated string of text easily</li> - </ul> +<div id="wrapper"> - <hr> +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> - <h3> - 1. Header files - </h3> - <p>The following are instructions required to compile an application that - uses the FreeType 2 library.</p> + <!-- ************************************************** --> - <ol> - <li> - <p><b><font size="+1">Locate the FreeType 2 <tt>include</tt> - directory.</font></b><br></p> + <div id="simple-glyph-loading"> + <h2>I. Simple Glyph Loading</h2> - <p>You have to add it to your compilation include path.</p> + <h3 id="section-1">1. Header Files</h3> - <p>Note that on Unix systems, you can now run the - <tt>freetype-config</tt> script with the <tt>--cflags</tt> option to - retrieve the appropriate compilation flags. This script can also be - used to check the version of the library that is installed on your - system, as well as the required librarian and linker flags.</p> - </li> + <p>The following are instructions required to compile an + application that uses the FreeType 2 library.</p> - <li> - <p><b><font size="+1">Include the file named - <tt>ft2build.h</tt>.</font></b></p> + <ol> + <li class="emph"> + <p>Locate the FreeType 2 <tt>include</tt> + directory.</p> - <p>It contains various macro declarations that are later used to - <tt>#include</tt> the appropriate public FreeType 2 header - files.</p> - </li> + <p>You have to add it to your compilation include + path.</p> - <li> - <p><b><font size="+1">Include the main FreeType 2 API header - file.</font></b></p> + <p>In Unix-like environments you can run the + <tt>freetype-config</tt> script with + the <tt>--cflags</tt> option to retrieve the + appropriate compilation flags. This script can also + be used to check the version of the library that is + installed on your system, as well as the required + librarian and linker flags.</p> + </li> - <p>You should do that using the macro <tt>FT_FREETYPE_H</tt>, - like in the following example:</p> + <li class="emph"> + <p>Include the file named <tt>ft2build.h</tt>.</p> - <div class="pre"> - #include <ft2build.h> - #include FT_FREETYPE_H - </div> + <p>It contains various macro declarations that are later + used to <tt>#include</tt> the appropriate public + FreeType 2 header files.</p> + </li> - <p><tt>FT_FREETYPE_H</tt> is a special macro defined in the file - <tt>ftheader.h</tt>. It contains some installation-specific macros - to name other public header files of the FreeType 2 API.</p> - - <p>You can read <a - href="../reference/ft2-header_file_macros.html">this section of the - FreeType 2 API Reference</a> for a complete listing of the - header macros.</p> - </li> - </ol> - - <p>The use of macros in <tt>#include</tt> statements is ANSI-compliant. - It is used for several reasons:</p> - - <ul> - <li> - <p>It avoids some painful conflicts with the FreeType 1.x public - header files.</p> - </li> - - <li> - <p>The macro names are not limited to the DOS 8.3 file naming limit; - names like <tt>FT_MULTIPLE_MASTERS_H</tt> or <tt>FT_SFNT_NAMES_H</tt> - are a lot more readable and explanatory than the real file names - <tt>ftmm.h</tt> and <tt>ftsnames.h</tt>.</p> - </li> - - <li> - <p>It allows special installation tricks that will not be discussed - here.</p> - </li> - </ul> - - <p><font color="red">NOTE: Starting with FreeType 2.1.6, the old - header file inclusion scheme is no longer supported. This means that - you now get an error if you do something like the following:</font></p> - - <div class="pre"> - #include <freetype/freetype.h> - #include <freetype/ftglyph.h> - ... - </div> + <li class="emph"> + <p>Include the main FreeType 2 API header file.</p> - <hr> + <p>You should do that using the + macro <tt>FT_FREETYPE_H</tt>, like in the following + example.</p> + <pre> +#include <ft2build.h> +#include FT_FREETYPE_H</pre> - <h3> - 2. Initialize the library - </h3> + <p><tt>FT_FREETYPE_H</tt> is a special macro defined in + file <tt>ftheader.h</tt>. It contains some + installation-specific macros to name other public + header files of the FreeType 2 API.</p> - <p>Simply create a variable of type <a - href="../reference/ft2-base_interface.html#FT_Library"> - <tt>FT_Library</tt></a> named, for example, <tt>library</tt>, and call - the function <a - href="../reference/ft2-base_interface.html#FT_Init_FreeType"> - <tt>FT_Init_FreeType</tt></a> as in</p> + <p>You can + read <a href="../reference/ft2-header_file_macros.html">this + section of the FreeType 2 API Reference</a> for a + complete listing of the header macros.</p> + </li> + </ol> - <div class="pre"> - #include <ft2build.h> - #include FT_FREETYPE_H + <p>The use of macros in <tt>#include</tt> statements is + ANSI-compliant. It is used for several reasons.</p> - FT_Library library; + <ul> + <li>It avoids conflicts with (deprecated) FreeType 1.x + public header files.</li> + <li>The macro names are not limited to the DOS 8.3 file + naming limit; names like <tt>FT_MULTIPLE_MASTERS_H</tt> + or <tt>FT_SFNT_NAMES_H</tt> are a lot more readable and + explanatory than the real file names + <tt>ftmm.h</tt> and <tt>ftsnames.h</tt>.</li> - ... + <li>It allows special installation tricks that will not be + discussed here.</li> + </ul> - error = FT_Init_FreeType( &library ); - if ( error ) - { - ... an error occurred during library initialization ... - } - </div> - <p>This function is in charge of the following:</p> + <h3 id="section-2">2. Library Initialization</h3> - <ul> - <li> - <p>It creates a new instance of the FreeType 2 library, and - sets the handle <tt>library</tt> to it.</p> - </li> + <p>To initialize the FreeType library, create a variable of + type <a href="../reference/ft2-base_interface.html#FT_Library"><tt>FT_Library</tt></a> + named, for example, <tt>library</tt>, and call the + function <a href="../reference/ft2-base_interface.html#FT_Init_FreeType"><tt>FT_Init_FreeType</tt></a>.</p> - <li> - <p>It loads each module that FreeType knows about in the library. - Among others, your new <tt>library</tt> object is able - to handle TrueType, Type 1, CID-keyed & OpenType/CFF fonts - gracefully.</p> - </li> - </ul> + <pre> +#include <ft2build.h> +#include FT_FREETYPE_H - <p>As you can see, the function returns an error code, like most others - in the FreeType API. An error code of 0 <em>always</em> means that - the operation was successful; otherwise, the value describes the error, - and <tt>library</tt> is set to NULL.</p> +FT_Library library; - <hr> +... - <h3> - 3. Load a font face - </h3> +error = FT_Init_FreeType( &library ); +if ( error ) +{ + ... an error occurred during library initialization ... +}</pre> - <h4> - a. From a font file - </h4> + <p>This function is in charge of</p> - <p>Create a new <tt>face</tt> object by calling <a - href="../reference/ft2-base_interface.html#FT_New_Face"> - <tt>FT_New_Face</tt></a>. A <em>face</em> describes a given typeface - and style. For example, ‘Times New Roman Regular’ and - ‘Times New Roman Italic’ correspond to two different - faces.</p> + <ul> + <li>creating a new instance of the FreeType 2 library + and setting the handle <tt>library</tt> to it, and</li> - <div class="pre"> - FT_Library library; <span class="comment">/* handle to library */</span> - FT_Face face; <span class="comment">/* handle to face object */</span> + <li>loading each module that FreeType knows about in the + library. Among others, your new <tt>library</tt> object + is able to handle TrueType, Type 1, CID-keyed & + OpenType/CFF fonts gracefully.</li> + </ul> + + <p>As you can see, the function returns an error code, like + most other functions of the FreeType API. An error code + of 0 (also known + as <tt>FT_Err_Ok</tt>) <em>always</em> means that the + operation was successful; otherwise, the value describes + the error, and <tt>library</tt> is set to NULL.</p> + + + <h3 id="section-3">3. Loading a Font Face</h3> + + <h4>a. From a Font File</h4> + + <p>Create a new <tt>face</tt> object by + calling <a href="../reference/ft2-base_interface.html#FT_New_Face"><tt>FT_New_Face</tt></a>. + A <em>face</em> describes a given typeface and style. For + example, ‘Times New Roman Regular’ and + ‘Times New Roman Italic’ correspond to two + different faces.</p> - - error = FT_Init_FreeType( &library ); - if ( error ) { ... } - - error = FT_New_Face( library, - "/usr/share/fonts/truetype/arial.ttf", - 0, - &face ); - if ( error == FT_Err_Unknown_File_Format ) - { - ... the font file could be opened and read, but it appears - ... that its font format is unsupported - } - else if ( error ) + <pre> +FT_Library library; <span class="comment">/* handle to library */</span> +FT_Face face; <span class="comment">/* handle to face object */</span> + + +error = FT_Init_FreeType( &library ); +if ( error ) { ... } + +error = FT_New_Face( library, + "/usr/share/fonts/truetype/arial.ttf", + 0, + &face ); +if ( error == FT_Err_Unknown_File_Format ) +{ + ... the font file could be opened and read, but it appears + ... that its font format is unsupported +} +else if ( error ) +{ + ... another error code means that the font file could not + ... be opened or read, or that it is broken... +}</pre> + + <p>As you can certainly imagine, <tt>FT_New_Face</tt> opens + a font file, then tries to extract one face from it. Its + parameters are as follows.</p> + + <dl> + <dt>library</dt> + <dd>A handle to the FreeType library instance where the + face object is created.</dd> + + <dt>filepathname</dt> + <dd>The font file pathname (a standard C string).</dd> + + <dt>face_index</dt> + <dd> + <p>Certain font formats allow several font faces to be + embedded in a single file.</p> + + <p>This index tells which face you want to load. An + error is returned if its value is too large.</p> + + <p>Index 0 always works, though.</p> + </dd> + + <dt>face</dt> + <dd> + <p>A <em>pointer</em> to the handle that is set to + describe the new face object.</p> + + <p>It is set to NULL in case of error.</p> + </dd> + </dl> + + <p>To know how many faces a given font file contains, load + its first face (this is, <tt>face_index</tt> should be set + to zero), then check the value + of <tt>face->num_faces</tt>, which indicates how many + faces are embedded in the font file.</p> + + <h4>b. From Memory</h4> + + <p>In the case where you have already loaded the font file + into memory, you can similarly create a new face object + for it by + calling <a href="../reference/ft2-base_interface.html#FT_New_Memory_Face"><tt>FT_New_Memory_Face</tt></a>.</p> + + <pre> +FT_Library library; <span class="comment">/* handle to library */</span> +FT_Face face; <span class="comment">/* handle to face object */</span> + + +error = FT_Init_FreeType( &library ); +if ( error ) { ... } + +error = FT_New_Memory_Face( library, + buffer, <span class="comment">/* first byte in memory */</span> + size, <span class="comment">/* size in bytes */</span> + 0, <span class="comment">/* face_index */</span> + &face ); +if ( error ) { ... }</pre> + + <p>As you can see, <tt>FT_New_Memory_Face</tt> takes a + pointer to the font file buffer and its size in bytes + instead of a file pathname. Other than that, it has + exactly the same semantics as + <tt>FT_New_Face</tt>.</p> + + <p>Note that you must not deallocate the memory before calling + <a href="../reference/ft2-base_interface.html#FT_Done_Face"><tt>FT_Done_Face</tt></a>.</p> + + <h4>c. From Other Sources (Compressed Files, Network, + etc.)</h4> + + <p>There are cases where using a file pathname or preloading + the file into memory is not sufficient. With + FreeType 2, it is possible to provide your own + implementation of I/O routines.</p> + + <p>This is done through + the <a href="../reference/ft2-base_interface.html#FT_Open_Face"><tt>FT_Open_Face</tt></a> + function, which can be used to open a new font face with a + custom input stream, select a specific driver for opening, + or even pass extra parameters to the font driver when + creating the object. We advise you to look up + the <a href="../reference/ft2-toc.html">FreeType 2 + reference manual</a> in order to learn how to use it.</p> + + + <h3 id="section-4">4. Accessing the Face Data</h3> + + <p>A <em>face object</em> models all information that + globally describes the face. Usually, this data can be + accessed directly by dereferencing a handle, like + in <tt>face−>num_glyphs</tt>.</p> + + <p>The complete list of available fields is in + the <a href="../reference/ft2-base_interface.html#FT_FaceRec"><tt>FT_FaceRec</tt></a> + structure description. However, we describe here a few of + them in more detail.</p> + + <dl> + <dt>num_glyphs</dt> + <dd>This variable gives the number of <em>glyphs</em> + available in the font face. A glyph is a character + image, nothing more – it thus doesn't necessarily + correspond to a <em>character code</em>.</dd> + + <dt>face_flags</dt> + <dd>A 32-bit integer containing bit flags that describe + some face properties. For example, the flag + <tt>FT_FACE_FLAG_SCALABLE</tt> indicates that the face's + font format is scalable and that glyph images can be + rendered for all character pixel sizes. For more + information on face flags, please read + the <a href="../reference/ft2-base_interface.html#FT_FACE_FLAG_XXX">FreeType 2 + API Reference</a>.</dd> + + <dt>units_per_EM</dt> + <dd>This field is only valid for scalable formats (it is + set to 0 otherwise). It indicates the number of + font units covered by the EM.</dd> + + <dt>num_fixed_sizes</dt> + <dd>This field gives the number of embedded bitmap strikes + in the current face. A <em>strike</em> is a series of + glyph images for a given character pixel size. For + example, a font face could include strikes for pixel + sizes 10, 12, and 14. Note that even scalable font + formats can have embedded bitmap strikes!</dd> + + <dt>available_sizes</dt> + <dd> + <p>A pointer to an array + of <a href="../reference/ft2-base_interface.html#FT_Bitmap_Size"><tt>FT_Bitmap_Size</tt></a> + elements. Each <tt>FT_Bitmap_Size</tt> indicates the + horizontal and vertical <em>character pixel sizes</em> + for each of the strikes that are present in the + face.</p> + + <p class="warning">Note that, generally speaking, these + are <em>not</em> the <em>cell size</em> of the bitmap + strikes.</p> + </dd> + </dl> + + + <h3 id="section-5">5. Setting the Current Pixel Size</h3> + + <p>FreeType 2 uses <em>size objects</em> to model all + information related to a given character size for a given + face. For example, a size object holds the value of + certain metrics like the ascender or text height, + expressed in 1/64th of a pixel, for a character size of + 12 points.</p> + + <p>When the <tt>FT_New_Face</tt> function is called (or one + of its siblings), it <em>automatically</em> creates a new + size object for the returned face. This size object is + directly accessible as + <tt>face−>size</tt>.</p> + + <p class="note">NOTE: A single face object can deal with one + or more size objects at a time; however, this is something + that few programmers really need to do. We have thus + decided to simplify the API for the most common use (i.e., + one size per face) while keeping this feature available + through additional functions.</p> + + <p>When a new face object is created, all elements are set + to 0 during initialization. To populate the + structure with sensible values, you should + call <a href="../reference/ft2-base_interface.html#FT_Set_Char_Size"><tt>FT_Set_Char_Size</tt></a>. + Here is an example, setting the character size to 16pt for + a 300×300dpi device:</p> + + <pre> +error = FT_Set_Char_Size( + face, <span class="comment">/* handle to face object */</span> + 0, <span class="comment">/* char_width in 1/64th of points */</span> + 16*64, <span class="comment">/* char_height in 1/64th of points */</span> + 300, <span class="comment">/* horizontal device resolution */</span> + 300 ); <span class="comment">/* vertical device resolution */</span></pre> + + <p>Some notes.</p> + + <ul> + <li>The character widths and heights are specified in + 1/64th of points. A point is a <em>physical</em> + distance, equaling 1/72th of an inch. Normally, it is + not equivalent to a pixel.</li> + + <li>Value of 0 for the character width means + ‘same as character height’, value of 0 + for the character height means ‘same as character + width’. Otherwise, it is possible to specify + different character widths and heights.</li> + + <li>The horizontal and vertical device resolutions are + expressed in <em>dots-per-inch</em>, or <em>dpi</em>. + Standard values are 72 or 96 dpi for display + devices like the screen. The resolution is used to + compute the character pixel size from the character + point size.</li> + + <li>Value of 0 for the horizontal resolution means + ‘same as vertical resolution’, value + of 0 for the vertical resolution means ‘same + as horizontal resolution’. If both values are + zero, 72 dpi is used for both dimensions.</li> + + <li>The first argument is a handle to a face object, not a + size object.</li> + </ul> + + <p>This function computes the character pixel size that + corresponds to the character width and height and device + resolutions. However, if you want to specify the pixel + sizes yourself, you can call + <a href="../reference/ft2-base_interface.html#FT_Set_Pixel_Sizes"><tt>FT_Set_Pixel_Sizes</tt></a>.</p> + + <pre> +error = FT_Set_Pixel_Sizes( + face, <span class="comment">/* handle to face object */</span> + 0, <span class="comment">/* pixel_width */</span> + 16 ); <span class="comment">/* pixel_height */</span></pre> + + <p>This example sets the character pixel sizes to + 16×16 pixels. As previously, a value of 0 + for one of the dimensions means ‘same as the + other’.</p> + + <p>Note that both functions return an error code. Usually, + an error occurs with a fixed-size font format (like FNT or + PCF) when trying to set the pixel size to a value that is + not listed in the <tt>face->fixed_sizes</tt> array.</p> + + + <h3 id="section-6">6. Loading a Glyph Image</h3> + + <h4>a. Converting a Character Code Into a Glyph Index</h4> + + <p>Normally, an application wants to load a glyph image + based on its <em>character code</em>, which is a unique + value that defines the character for a + given <em>encoding</em>. For example, code 65 (0x41) + represents character ‘A’ in ASCII + encoding.</p> + + <p>A face object contains one or more tables, called + <em>charmaps</em>, to convert character codes to glyph + indices. For example, most older TrueType fonts contain + two charmaps: One is used to convert Unicode character + codes to glyph indices, the other one is used to convert + Apple Roman encoding to glyph indices. Such fonts can + then be used either on Windows (which uses Unicode) and + old MacOS versions (which use Apple Roman). Note also + that a given charmap might not map to all the glyphs + present in the font.</p> + + <p>By default, when a new face object is created, it selects + a Unicode charmap. FreeType tries to emulate a Unicode + charmap if the font doesn't contain such a charmap, based + on glyph names. Note that it is possible that the + emulation misses glyphs if glyph names are non-standard. + For some fonts like symbol fonts, no Unicode emulation is + possible at all.</p> + + <p>Later on we will describe how to look for specific + charmaps in a face. For now, we assume that the face + contains at least a Unicode charmap that was selected + during a call to <tt>FT_New_Face</tt>. To convert a + Unicode character code to a font glyph index, we use + <a href="../reference/ft2-base_interface.html#FT_Get_Char_Index"><tt>FT_Get_Char_Index</tt></a>.</p> + + <pre> +glyph_index = FT_Get_Char_Index( face, charcode );</pre> + + <p>This code line looks up the glyph index corresponding to + the given <tt>charcode</tt> in the charmap that is + currently selected for the face. You should use the + UTF-32 representation form of Unicode; for example, if you + want to load character U+1F028, use value 0x1F028 as the + value for <tt>charcode</tt>. + + <p>If no charmap was selected, the function returns + the charcode.</p> + + <p>Note that this is one of the rare FreeType functions that + do not return an error code. However, when a given + character code has no glyph image in the face, + value 0 is returned. By convention, it always + corresponds to a special glyph image called + the <em>missing glyph</em>, which is commonly displayed as + a box or a space.</p> + + <h4>b. Loading a Glyph From the Face</h4> + + <p>Once you have a glyph index, you can load the + corresponding glyph image. The latter can be stored in + various formats within the font file. For fixed-size + formats like FNT or PCF, each image is a bitmap. Scalable + formats like TrueType or CFF use vectorial shapes + (<em>outlines</em>) to describe each glyph. Some formats + may have even more exotic ways of representing glyphs + (e.g., MetaFont – but this format is not supported). + Fortunately, FreeType 2 is flexible enough to support + any kind of glyph format through a simple API.</p> + + <p>The glyph image is always stored in a special object called a + <em>glyph slot</em>. As its name suggests, a glyph slot + is a container that is able to hold one glyph image at a + time, be it a bitmap, an outline, or something else. Each + face object has a single glyph slot object that can be + accessed as <tt>face->glyph</tt>. Its fields are + explained by + the <a href="../reference/ft2-base_interface.html#FT_GlyphSlotRec"><tt>FT_GlyphSlotRec</tt></a> + structure documentation.</p> + + <p>Loading a glyph image into the slot is performed by + calling <a href="../reference/ft2-base_interface.html#FT_Load_Glyph"><tt>FT_Load_Glyph</tt></a>.</p> + + <pre> +error = FT_Load_Glyph( + face, <span class="comment">/* handle to face object */</span> + glyph_index, <span class="comment">/* glyph index */</span> + load_flags ); <span class="comment">/* load flags, see below */</span></pre> + + <p>The <tt>load_flags</tt> value is a set of bit flags to + indicate some special operations. The default value + <tt>FT_LOAD_DEFAULT</tt> is 0.</p> + + <p>This function tries to load the corresponding glyph image + from the face.</p> + + <ul> + <li>If a bitmap is found for the corresponding glyph and + pixel size, it is loaded into the slot. Embedded + bitmaps are always favoured over native image formats, + because we assume that they are higher-quality versions + of the same glyph. This can be changed by using + the <tt>FT_LOAD_NO_BITMAP</tt> flag.</li> + + <li>Otherwise, a native image for the glyph is loaded. It + is also scaled to the current pixel size, as well as + hinted for certain formats like TrueType and + Type 1.</li> + </ul> + + <p>The field <tt>face−>glyph−>format</tt> + describes the format used for storing the glyph image in + the slot. If it is not <tt>FT_GLYPH_FORMAT_BITMAP</tt>, + one can immediately convert it to a bitmap + through <a href="../reference/ft2-base_interface.html#FT_Render_Glyph"><tt>FT_Render_Glyph</tt></a>.</p> + + <pre> +error = FT_Render_Glyph( face->glyph, <span class="comment">/* glyph slot */</span> + render_mode ); <span class="comment">/* render mode */</span></pre> + + <p>The parameter <tt>render_mode</tt> is a set of bit flags + to specify how to render the glyph image. + <tt>FT_RENDER_MODE_NORMAL</tt>, the default, renders an + anti-aliased bitmap with 256 gray levels (also called + a <em>pixmap</em>), as this is the default. You can + alternatively use <tt>FT_RENDER_MODE_MONO</tt> if you want + to generate a 1-bit monochrome bitmap. More values are + available for + the <a href="../reference/ft2-base_interface.html#FT_Render_Mode"><tt>FT_Render_Mode</tt></a> + enumeration value.</p> + + <p>Once you have a bitmapped glyph image, you can access it + directly through <tt>glyph->bitmap</tt> (a simple + descriptor for bitmaps or pixmaps), and position it + through <tt>glyph->bitmap_left</tt> and + <tt>glyph->bitmap_top</tt>.</p> + + <p>Note that <tt>bitmap_left</tt> is the horizontal distance + from the current pen position to the leftmost border of + the glyph bitmap, while <tt>bitmap_top</tt> is the + vertical distance from the pen position (on the baseline) + to the topmost border of the glyph bitmap. <em>It is + positive to indicate an upwards distance</em>.</p> + + <h4>c. Using Other Charmaps</h4> + + <p>As said before, when a new face object is created, it + looks for a Unicode charmap and select it. The currently + selected charmap can be accessed + via <tt>face->charmap</tt>. This field is NULL if no + charmap is selected, which typically happens when you + create a new <tt>FT_Face</tt> object from a font file that + doesn't contain a Unicode charmap (which is rather + infrequent today).</p> + + <p>There are two ways to select a different charmap with + FreeType. It's easiest if the encoding you need already + has a corresponding enumeration defined + in <tt>FT_FREETYPE_H</tt>, for + example <tt>FT_ENCODING_BIG5</tt>. In this case, you can + call + <a href="../reference/ft2-base_interface.html#FT_Select_Charmap"><tt>FT_Select_Charmap</tt></a>.</p> + + <pre> +error = FT_Select_Charmap( + face, <span class="comment">/* target face object */</span> + FT_ENCODING_BIG5 ); <span class="comment">/* encoding */</span></pre> + + <p>Another way is to manually parse the list of charmaps for + the face; this is accessible through the + fields <tt>num_charmaps</tt> and + <tt>charmaps</tt> (notice the ‘s’) of the face + object. As you could expect, the first is the number of + charmaps in the face, while the second is <em>a table of + pointers to the charmaps</em> embedded in the face.</p> + + <p>Each charmap has a few visible fields to describe it more + precisely. The most important ones are + <tt>charmap->platform_id</tt> + and <tt>charmap->encoding_id</tt>, defining a pair of + values that describe the charmap in a rather generic way: + Each value pair corresponds to a given encoding. For + example, the pair (3,1) corresponds to Unicode. The list + is defined in the TrueType specification; you can also use + the file <tt>FT_TRUETYPE_IDS_H</tt>, which defines several + helpful constants to deal with them.</p> + + <p>To select a specific encoding, you need to find a + corresponding value pair in the specification, then look + for it in the charmaps list. Don't forget that there are + encodings that correspond to several value pairs due to + historical reasons.</p> + + <pre> +FT_CharMap found = 0; +FT_CharMap charmap; +int n; + + +for ( n = 0; n < face->num_charmaps; n++ ) +{ + charmap = face->charmaps[n]; + if ( charmap->platform_id == my_platform_id && + charmap->encoding_id == my_encoding_id ) { - ... another error code means that the font file could not - ... be opened or read, or simply that it is broken... + found = charmap; + break; } - </div> - - <p>As you can certainly imagine, <tt>FT_New_Face</tt> opens a font - file, then tries to extract one face from it. Its parameters are</p> - - <table cellpadding=5> - <tr valign="top"> - <td> - <tt>library</tt> - </td> - <td> - <p>A handle to the FreeType library instance where the face object - is created.</p> - </td> - </tr> - <tr valign="top"> - <td> - <tt>filepathname</tt> - </td> - <td> - <p>The font file pathname (a standard C string).</p> - </td> - </tr> - <tr valign="top"> - <td> - <tt>face_index</tt> - </td> - <td> - <p>Certain font formats allow several font faces to be embedded - in a single file.</p> - - <p>This index tells which face you want to load. An error will - be returned if its value is too large.</p> - - <p>Index 0 always work though.</p> - </td> - </tr> - <tr valign="top"> - <td> - <tt>face</tt> - </td> - <td> - <p>A <em>pointer</em> to the handle that will be set to describe - the new face object.</p> - - <p>It is set to NULL in case of error.</p> - </td> - </tr> - </table> - - <p>To know how many faces a given font file contains, simply load its - first face (this is, <tt>face_index</tt> should be set to zero), then - check the value of <tt>face->num_faces</tt> which indicates how - many faces are embedded in the font file.</p> - - <h4> - b. From memory - </h4> - - <p>In the case where you have already loaded the font file into memory, - you can similarly create a new face object for it by calling <a - href="../reference/ft2-base_interface.html#FT_New_Memory_Face"> - <tt>FT_New_Memory_Face</tt></a> as in</p> - - <div class="pre"> - FT_Library library; <span class="comment">/* handle to library */</span> - FT_Face face; <span class="comment">/* handle to face object */</span> - - - error = FT_Init_FreeType( &library ); - if ( error ) { ... } - - error = FT_New_Memory_Face( library, - buffer, <span class="comment">/* first byte in memory */</span> - size, <span class="comment">/* size in bytes */</span> - 0, <span class="comment">/* face_index */</span> - &face ); - if ( error ) { ... } - </div> - - <p>As you can see, <tt>FT_New_Memory_Face</tt> simply takes a pointer - to the font file buffer and its size in bytes instead of a file - pathname. Other than that, it has exactly the same semantics as - <tt>FT_New_Face</tt>.</p> - - <p>Note that you must not deallocate the memory before calling - <tt>FT_Done_Face</tt>.</p> - - <h4> - c. From other sources (compressed files, network, etc.) - </h4> - - <p>There are cases where using a file pathname or preloading the file - into memory is simply not sufficient. With FreeType 2, it is - possible to provide your own implementation of i/o routines.</p> - - <p>This is done through the <a - href="../reference/ft2-base_interface.html#FT_Open_Face"> - <tt>FT_Open_Face</tt></a> function, which can be used to open a new - font face with a custom input stream, select a specific driver for - opening, or even pass extra parameters to the font driver when creating - the object. We advise you to refer to the FreeType 2 reference - manual in order to learn how to use it.</p> - - <hr> - - <h3> - 4. Accessing face content - </h3> - - <p>A <em>face object</em> models all information that globally describes - the face. Usually, this data can be accessed directly by dereferencing - a handle, like in <tt>face−>num_glyphs</tt>.</p> - - <p>The complete list of available fields in in the <a - href="../reference/ft2-base_interface.html#FT_FaceRec"> - <tt>FT_FaceRec</tt></a> structure description. However, we describe - here a few of them in more details: - </p> - - <table cellpadding=5> - <tr valign="top"> - <td> - <tt>num_glyphs</tt> - </td> - <td> - <p>This variable gives the number of <em>glyphs</em> available in - the font face. A glyph is simply a character image. It doesn't - necessarily correspond to a <em>character code</em> though.</p> - </td> - </tr> - <tr valign="top"> - <td> - <tt>face_flags</tt> - </td> - <td> - <p>A 32-bit integer containing bit flags used to describe some - face properties. For example, the flag - <tt>FT_FACE_FLAG_SCALABLE</tt> is used to indicate that the face's - font format is scalable and that glyph images can be rendered for - all character pixel sizes. For more information on face flags, - please read the <a - href="../reference/ft2-index.html">FreeType 2 API - Reference</a>.</p> - </td> - </tr> - <tr valign="top"> - <td> - <tt>units_per_EM</tt> - </td> - <td> - <p>This field is only valid for scalable formats (it is set - to 0 otherwise). It indicates the number of font units - covered by the EM.</p> - </td> - </tr> - <tr valign="top"> - <td> - <tt>num_fixed_sizes</tt> - </td> - <td> - <p>This field gives the number of embedded bitmap strikes - in the current face. A <em>strike</em> is simply a series of - glyph images for a given character pixel size. For example, a - font face could include strikes for pixel sizes 10, 12 - and 14. Note that even scalable font formats can have - embedded bitmap strikes!</p> - </td> - </tr> - <tr valign="top"> - <td> - <tt>available_sizes</tt> - </td> - <td> - <p>A pointer to an array of <tt>FT_Bitmap_Size</tt> - elements. Each <tt>FT_Bitmap_Size</tt> indicates the horizontal - and vertical <em>character pixel sizes</em> for each of the strikes - that are present in the face.</p> - - <p><font color="red">Note that, generally speaking, these are - <em>not</em> the <em>cell size</em> of the bitmap strikes.</font> - </p> - </td> - </tr> - </table> - - <hr> - - <h3> - 5. Setting the current pixel size - </h3> - - <p>FreeType 2 uses <em>size objects</em> to model all information - related to a given character size for a given face. For example, a size - object will hold the value of certain metrics like the ascender or text - height, expressed in 1/64th of a pixel, for a character size of - 12 points.</p> - - <p>When the <tt>FT_New_Face</tt> function is called (or one of its - cousins), it <em>automatically</em> creates a new size object for the - returned face. This size object is directly accessible as - <tt>face−>size</tt>.</p> - - <p><em>NOTE: A single face object can deal with one or more size - objects at a time; however, this is something that few programmers - really need to do. We have thus decided to simplify the API for the - most common use (i.e., one size per face) while keeping this feature - available through additional functions.</em></p> - - <p>When a new face object is created, all elements are set to 0 - during initialization. To populate the structure with sensible values, - simply call <a - href="../reference/ft2-base_interface.html#FT_Set_Char_Size"> - <tt>FT_Set_Char_Size</tt></a>. Here is an example where the character - size is set to 16pt for a 300×300dpi device:</p> - - <div class="pre"> - error = FT_Set_Char_Size( - face, <span class="comment">/* handle to face object */</span> - 0, <span class="comment">/* char_width in 1/64th of points */</span> - 16*64, <span class="comment">/* char_height in 1/64th of points */</span> - 300, <span class="comment">/* horizontal device resolution */</span> - 300 ); <span class="comment">/* vertical device resolution */</span> - </div> - - <p>Some notes:</p> - - <ul> - <li> - <p>The character widths and heights are specified in 1/64th of - points. A point is a <em>physical</em> distance, equaling 1/72th - of an inch. Normally, it is not equivalent to a pixel.<p> - </li> - - <li> - <p>A value of 0 for the character width means ‘same as - character height’, a value of 0 for the character height - means ‘same as character width’. Otherwise, it is - possible to specify different character widths and heights.</p> - </li> - - <li> - <p>The horizontal and vertical device resolutions are expressed in - <em>dots-per-inch</em>, or <em>dpi</em>. Normal values are 72 or - 96 dpi for display devices like the screen. The resolution - is used to compute the character pixel size from the character - point size.</p> - </li> - - <li> - <p>A value of 0 for the horizontal resolution means - ‘same as vertical resolution’, a value of 0 for the - vertical resolution means ‘same as horizontal - resolution’. If both values are zero, 72 dpi is used for - both dimensions.</p> - </li> - - <li> - <p>The first argument is a handle to a face object, not a size - object.</p> - </li> - </ul> - - <p>This function computes the character pixel size that corresponds to - the character width and height and device resolutions. However, if you - want to specify the pixel sizes yourself, you can simply call - <a href="../reference/ft2-base_interface.html#FT_Set_Pixel_Sizes"> - <tt>FT_Set_Pixel_Sizes</tt></a>, as in</p> - - <div class="pre"> - error = FT_Set_Pixel_Sizes( - face, <span class="comment">/* handle to face object */</span> - 0, <span class="comment">/* pixel_width */</span> - 16 ); <span class="comment">/* pixel_height */</span> - </div> - - <p>This example will set the character pixel sizes to - 16×16 pixels. As previously, a value of 0 for one of - the dimensions means ‘same as the other’.</p> - - <p>Note that both functions return an error code. Usually, an error - occurs with a fixed-size font format (like FNT or PCF) when trying to - set the pixel size to a value that is not listed in the - <tt>face->fixed_sizes</tt> array.</p> - - <hr> - - <h3> - 6. Loading a glyph image - </h3> - - <h4> - a. Converting a character code into a glyph index - </h4> - - <p>Usually, an application wants to load a glyph image based on its - <em>character code</em>, which is a unique value that defines the - character for a given <em>encoding</em>. For example, the character - code 65 represents the ‘A’ in ASCII encoding.</p> - - <p>A face object contains one or more tables, called - <em>charmaps</em>, that are used to convert character codes to glyph - indices. For example, most TrueType fonts contain two charmaps. One - is used to convert Unicode character codes to glyph indices, the other - is used to convert Apple Roman encoding into glyph indices. Such - fonts can then be used either on Windows (which uses Unicode) and - Macintosh (which uses Apple Roman). Note also that a given - charmap might not map to all the glyphs present in the font.</p> - - <p>By default, when a new face object is created, it selects a - Unicode charmap. FreeType tries to emulate a Unicode charmap if the - font doesn't contain such a charmap, based on glyph names. Note that - it is possible that the emulation misses glyphs if glyph names are - non-standard. For some fonts, including symbol fonts and (older) - fonts for Asian scripts, no Unicode emulation is possible at all.</p> - - <p>We will describe later how to look for specific charmaps in a face. - For now, we will assume that the face contains at least a Unicode - charmap that was selected during a call to <tt>FT_New_Face</tt>. To - convert a Unicode character code to a font glyph index, we use - <tt>FT_Get_Char_Index</tt>, as in</p> - - <div class="pre"> - glyph_index = FT_Get_Char_Index( face, charcode ); - </div> +} - <p>This will look up the glyph index corresponding to the given - <tt>charcode</tt> in the charmap that is currently selected for the - face. You should use the UTF-32 representation form of Unicode; for - example, if you want to load character U+1F028, use value 0x1F028 as - the value for <tt>charcode</tt>. - - <p>If no charmap was selected, the function simply returns the - charcode.</p> - - <p>Note that this is one of the rare FreeType functions that do not - return an error code. However, when a given character code has no - glyph image in the face, the value 0 is returned. By convention, - it always corresponds to a special glyph image called the <em>missing - glyph</em>, which is commonly displayed as a box or a space.</p> - - <h4> - b. Loading a glyph from the face - </h4> - - <p>Once you have a glyph index, you can load the corresponding glyph - image. The latter can be stored in various formats within the font - file. For fixed-size formats like FNT or PCF, each image is a bitmap. - Scalable formats like TrueType or Type 1 use vectorial shapes, - named <em>outlines</em> to describe each glyph. Some formats may have - even more exotic ways of representing glyphs (e.g., MetaFont — - but this format is not supported). Fortunately, FreeType 2 is - flexible enough to support any kind of glyph format through a simple - API.</p> - - <p>The glyph image is always stored in a special object called a - <em>glyph slot</em>. As its name suggests, a glyph slot is simply a - container that is able to hold one glyph image at a time, be it a - bitmap, an outline, or something else. Each face object has a single - glyph slot object that can be accessed as <tt>face->glyph</tt>. - Its fields are explained by the <a - href="../reference/ft2-base_interface.html#FT_GlyphSlotRec"> - <tt>FT_GlyphSlotRec</tt></a> structure documentation.</p> - - <p>Loading a glyph image into the slot is performed by calling <a - href="../reference/ft2-base_interface.html#FT_Load_Glyph"> - <tt>FT_Load_Glyph</tt></a> as in</p> - - <div class="pre"> - error = FT_Load_Glyph( - face, <span class="comment">/* handle to face object */</span> - glyph_index, <span class="comment">/* glyph index */</span> - load_flags ); <span class="comment">/* load flags, see below */</span> - </div> +if ( !found ) { ... } - <p>The <tt>load_flags</tt> value is a set of bit flags used to - indicate some special operations. The default value - <tt>FT_LOAD_DEFAULT</tt> is 0.</p> - - <p>This function will try to load the corresponding glyph image - from the face:</p> - - <ul> - <li> - <p>If a bitmap is found for the corresponding glyph and pixel - size, it will be loaded into the slot. Embedded bitmaps are - always favored over native image formats, because we assume that - they are higher-quality versions of the same glyph. This can be - changed by using the <tt>FT_LOAD_NO_BITMAP</tt> flag.</p> - </li> - - <li> - <p>Otherwise, a native image for the glyph will be loaded. It - will also be scaled to the current pixel size, as well as hinted - for certain formats like TrueType and Type 1.</p> - </li> - </ul> - - <p>The field <tt>face−>glyph−>format</tt> describes - the format used to store the glyph image in the slot. If it is not - <tt>FT_GLYPH_FORMAT_BITMAP</tt>, one can immediately convert it to a - bitmap through <a - href="../reference/ft2-base_interface.html#FT_Render_Glyph"> - <tt>FT_Render_Glyph</tt></a> as in:</p> - - <div class="pre"> - error = FT_Render_Glyph( face->glyph, <span class="comment">/* glyph slot */</span> - render_mode ); <span class="comment">/* render mode */</span> - </div> +<span class="comment">/* now, select the charmap for the face object */</span> +error = FT_Set_Charmap( face, found ); +if ( error ) { ... }</pre> - <p>The parameter <tt>render_mode</tt> is a set of bit flags used to - specify how to render the glyph image. Set it to - <tt>FT_RENDER_MODE_NORMAL</tt> to render a high-quality anti-aliased - (256 gray levels) bitmap, as this is the default. You can - alternatively use <tt>FT_RENDER_MODE_MONO</tt> if you want to generate - a 1-bit monochrome bitmap.</p> - - <p>Once you have a bitmapped glyph image, you can access it directly - through <tt>glyph->bitmap</tt> (a simple bitmap descriptor), and - position it through <tt>glyph->bitmap_left</tt> and - <tt>glyph->bitmap_top</tt>.</p> - - <p>Note that <tt>bitmap_left</tt> is the horizontal distance from the - current pen position to the leftmost border of the glyph bitmap, while - <tt>bitmap_top</tt> is the vertical distance from the pen position (on - the baseline) to the topmost border of the glyph bitmap. <em>It is - positive to indicate an upwards distance</em>.</p> - - <p>The next section will give more details on the contents of a glyph - slot and how to access specific glyph information (including - metrics).</p> - - <h4> - c. Using other charmaps - </h4> - - <p>As said before, when a new face object is created, it will look for - a Unicode charmap and select it. The currently selected charmap is - accessed via <tt>face->charmap</tt>. This field is NULL when no - charmap is selected, which typically happens when you create a new - <tt>FT_Face</tt> object from a font file that doesn't contain a - Unicode charmap (which is rather infrequent today).</p> - - <p>There are two ways to select a different charmap with - FreeType 2. The easiest is when the encoding you need already - has a corresponding enumeration defined in <tt>FT_FREETYPE_H</tt>, for - example <tt>FT_ENCODING_BIG5</tt>. In this case, you can simply call - <a href="../reference/ft2-base_interface.html#FT_Select_CharMap"> - <tt>FT_Select_CharMap</tt></a> as in:</p> - - <div class="pre"> - error = FT_Select_CharMap( - face, <span class="comment">/* target face object */</span> - FT_ENCODING_BIG5 ); <span class="comment">/* encoding */</span> - </div> + <p>Once a charmap has been selected, either through + <tt>FT_Select_Charmap</tt> + or <a href="../reference/ft2-base_interface.html#FT_Set_Charmap"><tt>FT_Set_Charmap</tt></a>, + it is used by all subsequent calls + to <tt>FT_Get_Char_Index</tt>.</p> - <p>Another way is to manually parse the list of charmaps for the face; - this is accessible through the fields <tt>num_charmaps</tt> and - <tt>charmaps</tt> (notice the ‘s&rsquo) of the face object. As - you could expect, the first is the number of charmaps in the face, - while the second is <em>a table of pointers to the charmaps</em> - embedded in the face.</p> - - <p>Each charmap has a few visible fields used to describe it more - precisely. Mainly, one will look at <tt>charmap->platform_id</tt> - and <tt>charmap->encoding_id</tt> that define a pair of values - that can be used to describe the charmap in a rather generic way.</p> - - <p>Each value pair corresponds to a given encoding. For example, the - pair (3,1) corresponds to Unicode. The list is defined in the - TrueType specification but you can also use the file - <tt>FT_TRUETYPE_IDS_H</tt> which defines several helpful constants to - deal with them.</p> - - <p>To select a specific encoding, you need to find a corresponding - value pair in the specification, then look for it in the charmaps - list. Don't forget that there are encodings which correspond to - several value pairs due to historical reasons. Here some code to do - it:</p> - - <div class="pre"> - FT_CharMap found = 0; - FT_CharMap charmap; - int n; - - - for ( n = 0; n < face->num_charmaps; n++ ) - { - charmap = face->charmaps[n]; - if ( charmap->platform_id == my_platform_id && - charmap->encoding_id == my_encoding_id ) - { - found = charmap; - break; - } - } + <h4>d. Glyph Transformations</h4> - if ( !found ) { ... } + <p>It is possible to specify an affine transformation with + <a href="../reference/ft2-base_interface.html#FT_Set_Transform"><tt>FT_Set_Transform</tt></a>, + to be applied to glyph images when they are loaded. Of + course, this only works for scalable (vectorial) font + formats.</p> - <span class="comment">/* now, select the charmap for the face object */</span> - error = FT_Set_CharMap( face, found ); - if ( error ) { ... } - </div> + <pre> +error = FT_Set_Transform( + face, <span class="comment">/* target face object */</span> + &matrix, <span class="comment">/* pointer to 2x2 matrix */</span> + &delta ); <span class="comment">/* pointer to 2d vector */</span></pre> - <p>Once a charmap has been selected, either through - <tt>FT_Select_CharMap</tt> or <tt>FT_Set_CharMap</tt>, it is used by - all subsequent calls to <tt>FT_Get_Char_Index</tt>.</p> + <p>This function sets the current transformation for a given + face object. Its second parameter is a pointer to an + <a href="../reference/ft2-basic_types.html#FT_Matrix"><tt>FT_Matrix</tt></a> + structure that describes a 2×2 affine matrix. The + third parameter is a pointer to + an <a href="../reference/ft2-basic_types.html#FT_Vector"><tt>FT_Vector</tt></a> + structure, describing a two-dimensional vector that + translates the glyph image <em>after</em> the 2×2 + transformation.</p> - <h4> - d. Glyph transformations - </h4> + <p>Note that the matrix pointer can be set to NULL, in which + case the identity transformation is used. Coefficients of + the matrix are otherwise in 16.16 fixed-point units.</p> - <p>It is possible to specify an affine transformation to be applied to - glyph images when they are loaded. Of course, this will only work for - scalable (vectorial) font formats.</p> + <p>The vector pointer can also be set to NULL (in which case + a delta of (0,0) is used). The vector coordinates are + expressed in 1/64th of a pixel (also known as 26.6 + fixed-point numbers).</p> - <p>To do that, simply call <a - href="../reference/ft2-base_interface.html#FT_Set_Transform"> - <tt>FT_Set_Transform</tt></a>, as in:</p> + <p class="warning">The transformation is applied to every + glyph that is loaded through <tt>FT_Load_Glyph</tt> and + is <em>completely independent of any hinting process</em>. + This means that you won't get the same results if you load + a glyph at the size of 24 pixels, or a glyph at the + size of 12 pixels scaled by 2 through a + transformation, because the hints are computed differently + (except if you have disabled hints).</p> - <div class="pre"> - error = FT_Set_Transform( - face, <span class="comment">/* target face object */</span> - &matrix, <span class="comment">/* pointer to 2x2 matrix */</span> - &delta ); <span class="comment">/* pointer to 2d vector */</span> - </div> + <p>If you ever need to use a non-orthogonal transformation + with optimal hints, you first have to decompose your + transformation into a scaling part and a rotation/shearing + part. Use the scaling part to compute a new character + pixel size, then the other one to call + <tt>FT_Set_Transform</tt>. This is explained in more + detail in part II of this tutorial.</p> - <p>This function will set the current transform for a given face - object. Its second parameter is a pointer to a simple <a - href="../reference/ft2-basic_types.html#FT_Matrix"> - <tt>FT_Matrix</tt></a> structure that describes a 2×2 affine - matrix. The third parameter is a pointer to a <a - href="../reference/ft2-basic_types.html#FT_Vector"> - <tt>FT_Vector</tt></a> structure that describes a simple - two-dimensional vector that is used to translate the glyph image - <em>after</em> the 2×2 transformation.</p> + <p class="warning">Rotation usually disables hinting.</p> - <p>Note that the matrix pointer can be set to NULL, in which case the - identity transform will be used. Coefficients of the matrix are - otherwise in 16.16 fixed-point units.</p> + <p>Loading a glyph bitmap with a non-identity transformation + works; the transformation is ignored in this case.</p> - <p>The vector pointer can also be set to NULL (in which case a delta - of (0,0) will be used). The vector coordinates are expressed in - 1/64th of a pixel (also known as 26.6 fixed-point numbers).</p> - <p><font color="red">NOTE: The transformation is applied to every - glyph that is loaded through <tt>FT_Load_Glyph</tt> and is - <em>completely independent of any hinting process</em>. This means - that you won't get the same results if you load a glyph at the size of - 24 pixels, or a glyph at the size of 12 pixels scaled - by 2 through a transform, because the hints will have been - computed differently (except you have disabled hints).</font></p> + <h3 id="section-7">7. Simple Text Rendering</h3> - <p>If you ever need to use a non-orthogonal transformation with - optimal hints, you first have to decompose your transformation into a - scaling part and a rotation/shearing part. Use the scaling part to - compute a new character pixel size, then the other one to call - <tt>FT_Set_Transform</tt>. This is explained in details in a later - section of this tutorial.</p> + <p>We now present a simple example to render a string of + 8-bit Latin-1 text, assuming a face that contains a + Unicode charmap.</p> - <p><font color="red">NOTE2: Rotation usually disables hinting.</font></p> + <p>The idea is to create a loop that loads one glyph image + on each iteration, converts it to a pixmap, draws it on + the target surface, then increments the current pen + position.</p> - <p>Loading a glyph bitmap with a non-identity transformation works; - the transformation is ignored in this case.</p> + <h4 id="basic-code">a. Basic Code</h4> - <hr> + <p>The following code performs our simple text rendering + with the functions previously described.</p> - <h3> - 7. Simple text rendering - </h3> + <pre> +FT_GlyphSlot slot = face->glyph; <span class="comment">/* a small shortcut */</span> +int pen_x, pen_y, n; - <p>We will now present a very simple example used to render a string of - 8-bit Latin-1 text, assuming a face that contains a Unicode charmap.</p> - <p>The idea is to create a loop that will, on each iteration, load one - glyph image, convert it to an anti-aliased bitmap, draw it on the target - surface, then increment the current pen position.</p> +... initialize library ... +... create face object ... +... set character size ... - <h4> - a. Basic code - </h4> +pen_x = 300; +pen_y = 200; - <p>The following code performs our simple text rendering with the - functions previously described.</p> +for ( n = 0; n < num_chars; n++ ) +{ + FT_UInt glyph_index; - <div class="pre"> - FT_GlyphSlot slot = face->glyph; <span class="comment">/* a small shortcut */</span> - int pen_x, pen_y, n; + <span class="comment">/* retrieve glyph index from character code */</span> + glyph_index = FT_Get_Char_Index( face, text[n] ); - ... initialize library ... - ... create face object ... - ... set character size ... + <span class="comment">/* load glyph image into the slot (erase previous one) */</span> + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); + if ( error ) + continue; <span class="comment">/* ignore errors */</span> - pen_x = 300; - pen_y = 200; + <span class="comment">/* convert to an anti-aliased bitmap */</span> + error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL ); + if ( error ) + continue; + + <span class="comment">/* now, draw to our target surface */</span> + my_draw_bitmap( &slot->bitmap, + pen_x + slot->bitmap_left, + pen_y - slot->bitmap_top ); + + <span class="comment">/* increment pen position */</span> + pen_x += slot->advance.x >> 6; + pen_y += slot->advance.y >> 6; <span class="comment">/* not useful for now */</span> +}</pre> + + <p>This code needs a few explanations.</p> + + <ul> + <li>We define a handle named <tt>slot</tt> that points to + the face object's glyph slot. (The + type <a href="../reference/ft2-base_interface.html#FT_GlyphSlot"><tt>FT_GlyphSlot</tt></a> + is a pointer). That is a convenience to avoid using + <tt>face->glyph->XXX</tt> every time.</li> + + <li>We increment the pen position with the vector + <tt>slot->advance</tt>, which correspond to the + glyph's <em>advance width</em> (also known as + its <em>escapement</em>). The advance vector is + expressed in 1/64th of pixels, and is truncated to + integer pixels on each iteration.</li> + + <li>The function <tt>my_draw_bitmap</tt> is not part of + FreeType but must be provided by the application to draw + the bitmap to the target surface. In this example, it + takes a pointer to + an <a href="../reference/ft2-basic_types.html#FT_Bitmap"><tt>FT_Bitmap</tt></a> + descriptor and the position of its top-left corner as + arguments.</li> + + <li>The value of <tt>slot->bitmap_top</tt> is positive + for an <em>upwards</em> vertical distance. Assuming + that the coordinates taken by <tt>my_draw_bitmap</tt> + use the opposite convention (increasing Y + corresponds to downwards scanlines), we subtract it + from <tt>pen_y</tt>, instead of adding to it.</li> + </ul> + + <h4>b.Refined code</h4> + + <p>The following code is a refined version of the example + above. It uses features and functions of FreeType that + have not yet been introduced, and which are explained + below.</p> + + <pre> +FT_GlyphSlot slot = face->glyph; <span class="comment">/* a small shortcut */</span> +FT_UInt glyph_index; +int pen_x, pen_y, n; + + +... initialize library ... +... create face object ... +... set character size ... + +pen_x = 300; +pen_y = 200; + +for ( n = 0; n < num_chars; n++ ) +{ + <span class="comment">/* load glyph image into the slot (erase previous one) */</span> + error = FT_Load_Char( face, text[n], FT_LOAD_RENDER ); + if ( error ) + continue; <span class="comment">/* ignore errors */</span> + + <span class="comment">/* now, draw to our target surface */</span> + my_draw_bitmap( &slot->bitmap, + pen_x + slot->bitmap_left, + pen_y - slot->bitmap_top ); + + <span class="comment">/* increment pen position */</span> + pen_x += slot->advance.x >> 6; +}</pre> + + <p>We have reduced the size of our code, but it does exactly + the same thing.</p> + + <ul> + <li>We use the + function <a href="../reference/ft2-base_interface.html#FT_Load_Char"><tt>FT_Load_Char</tt></a> + instead of <tt>FT_Load_Glyph</tt>. As you probably + imagine, it is equivalent to + calling <tt>FT_Get_Char_Index</tt>, then + <tt>FT_Load_Glyph</tt>.</li> + + <li> + <p>We do not use <tt>FT_LOAD_DEFAULT</tt> for the + loading mode, but the bit + flag <tt>FT_LOAD_RENDER</tt>. It indicates that the + glyph image must be immediately converted to an + anti-aliased bitmap. This is of course a shortcut + that avoids calling <tt>FT_Render_Glyph</tt> + explicitly but is strictly equivalent.</p> + + <p>Note that you can also specify that you want a + monochrome bitmap instead by using the + additional <tt>FT_LOAD_MONOCHROME</tt> load flag.</p> + </li> + </ul> + + <h4 id="transformed-text">c. More Advanced Rendering</h4> + + <p>Let us try to render transformed text now (for example + through a rotation). We can do this + using <tt>FT_Set_Transform</tt>.</p> + + <pre> +FT_GlyphSlot slot; +FT_Matrix matrix; <span class="comment">/* transformation matrix */</span> +FT_UInt glyph_index; +FT_Vector pen; <span class="comment">/* untransformed origin */</span> +int n; + + +... initialize library ... +... create face object ... +... set character size ... + +slot = face->glyph; <span class="comment">/* a small shortcut */</span> + +<span class="comment">/* set up matrix */</span> +matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); +matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); +matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); +matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L ); + +<span class="comment">/* the pen position in 26.6 cartesian space coordinates */</span> +<span class="comment">/* start at (300,200) */</span> +pen.x = 300 * 64; +pen.y = ( my_target_height - 200 ) * 64; + +for ( n = 0; n < num_chars; n++ ) +{ + <span class="comment">/* set transformation */</span> + FT_Set_Transform( face, &matrix, &pen ); + + <span class="comment">/* load glyph image into the slot (erase previous one) */</span> + error = FT_Load_Char( face, text[n], FT_LOAD_RENDER ); + if ( error ) + continue; <span class="comment">/* ignore errors */</span> + + <span class="comment">/* now, draw to our target surface (convert position) */</span> + my_draw_bitmap( &slot->bitmap, + slot->bitmap_left, + my_target_height - slot->bitmap_top ); + + <span class="comment">/* increment pen position */</span> + pen.x += slot->advance.x; + pen.y += slot->advance.y; +}</pre> + + <p>Some remarks.</p> + + <ul> + <li>We now use a vector of type <tt>FT_Vector</tt> to + store the pen position, with coordinates expressed as + 1/64th of pixels, hence a multiplication. The position + is expressed in cartesian space.</li> + + <li>Glyph images are always loaded, transformed, and + described in the cartesian coordinate system within + FreeType (which means that increasing Y corresponds + to upper scanlines), unlike the system typically used + for bitmaps (where the topmost scanline has + coordinate 0). We must thus convert between the + two systems when we define the pen position, and when we + compute the topleft position of the bitmap.</li> + + <li>We set the transformation on each glyph to indicate + the rotation matrix as well as a delta that moves the + transformed image to the current pen position (in + cartesian space, not bitmap space). As a consequence, + the values of <tt>bitmap_left</tt> + and <tt>bitmap_top</tt> correspond to the bitmap origin + in target space pixels. We thus don't + add <tt>pen.x</tt> or <tt>pen.y</tt> to their values + when calling <tt>my_draw_bitmap</tt>.</li> + + <li>The advance width is always returned transformed, + which is why it can be directly added to the current pen + position. Note that it is <em>not</em> rounded this + time.</li> + </ul> + + <p>A complete source code example can be found + <a href="example1.c">here</a>.</p> + + <p>It is important to note that, while this example is a bit + more complex than the previous one, it is strictly + equivalent for the case where the transformation is the + identity. Hence it can be used as a replacement (but a + more powerful one).</p> + + <p>The still present few shortcomings will be explained, and + solved, in the next part of this tutorial.</p> + </div> - for ( n = 0; n < num_chars; n++ ) - { - FT_UInt glyph_index; + <!-- ************************************************** --> + <div class="updated"> + <p>Last update: 10-Dec-2014</p> + </div> + </div> + </div> - <span class="comment">/* retrieve glyph index from character code */</span> - glyph_index = FT_Get_Char_Index( face, text[n] ); - <span class="comment">/* load glyph image into the slot (erase previous one) */</span> - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); - if ( error ) - continue; <span class="comment">/* ignore errors */</span> + <!-- ************************************************** --> - <span class="comment">/* convert to an anti-aliased bitmap */</span> - error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL ); - if ( error ) - continue; + <div class="col2"> + </div> + </div> +</div> - <span class="comment">/* now, draw to our target surface */</span> - my_draw_bitmap( &slot->bitmap, - pen_x + slot->bitmap_left, - pen_y - slot->bitmap_top ); - <span class="comment">/* increment pen position */</span> - pen_x += slot->advance.x >> 6; - pen_y += slot->advance.y >> 6; <span class="comment">/* not useful for now */</span> - } - </div> +<!-- ************************************************** --> - <p>This code needs a few explanations:</p> - - <ul> - <li> - <p>We define a handle named <tt>slot</tt> that points to the - face object's glyph slot. (The type <tt>FT_GlyphSlot</tt> is - a pointer). That is a convenience to avoid using - <tt>face->glyph->XXX</tt> every time.</p> - </li> - - <li> - <p>We increment the pen position with the vector - <tt>slot->advance</tt>, which correspond to the glyph's - <em>advance width</em> (also known as its <em>escapement</em>). - The advance vector is expressed in 1/64th of pixels, and is - truncated to integer pixels on each iteration.</p> - </li> - - <li> - <p>The function <tt>my_draw_bitmap</tt> is not part of FreeType - but must be provided by the application to draw the bitmap to the - target surface. In this example, it takes a pointer to a - FT_Bitmap descriptor and the position of its top-left corner as - arguments.</p> - </li> - - <li> - <p>The value of <tt>slot->bitmap_top</tt> is positive for an - <em>upwards</em> vertical distance. Assuming that the coordinates - taken by <tt>my_draw_bitmap</tt> use the opposite convention - (increasing Y corresponds to downwards scanlines), we - subtract it from <tt>pen_y</tt>, instead of adding to it.</p> - </li> - </ul> - - <h4> - b. Refined code - </h4> - - <p>The following code is a refined version of the example above. It - uses features and functions of FreeType 2 that have not yet been - introduced, and which are explained below:</p> - - <div class="pre"> - FT_GlyphSlot slot = face->glyph; <span class="comment">/* a small shortcut */</span> - FT_UInt glyph_index; - int pen_x, pen_y, n; - - - ... initialize library ... - ... create face object ... - ... set character size ... - - pen_x = 300; - pen_y = 200; - - for ( n = 0; n < num_chars; n++ ) - { - <span class="comment">/* load glyph image into the slot (erase previous one) */</span> - error = FT_Load_Char( face, text[n], FT_LOAD_RENDER ); - if ( error ) - continue; <span class="comment">/* ignore errors */</span> - - <span class="comment">/* now, draw to our target surface */</span> - my_draw_bitmap( &slot->bitmap, - pen_x + slot->bitmap_left, - pen_y - slot->bitmap_top ); - - <span class="comment">/* increment pen position */</span> - pen_x += slot->advance.x >> 6; - } - </div> +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="index.html">FreeType Tutorial</a> + </li> + <li class="tertiary"> + <a href="step1.html" class="current">Simple Glyph Loading</a> + </li> + <li class="tertiary"> + <a href="step2.html">Managing Glyphs</a> + </li> + <li class="tertiary"> + <a href="step3.html">Examples</a> + </li> + </ul> +</div> - <p>We have reduced the size of our code, but it does exactly the - same thing:</p> - - <ul> - <li> - <p>We use the function <tt>FT_Load_Char</tt> instead of - <tt>FT_Load_Glyph</tt>. As you probably imagine, it is equivalent - to calling <tt>FT_Get_Char_Index</tt> then - <tt>FT_Load_Glyph</tt>.</p> - </li> - - <li> - <p>We do not use <tt>FT_LOAD_DEFAULT</tt> for the loading mode, - but the bit flag <tt>FT_LOAD_RENDER</tt>. It indicates that the - glyph image must be immediately converted to an anti-aliased - bitmap. This is of course a shortcut that avoids calling - <tt>FT_Render_Glyph</tt> explicitly but is strictly - equivalent.</p> - - <p>Note that you can also specify that you want a monochrome - bitmap instead by using the addition <tt>FT_LOAD_MONOCHROME</tt> - load flag.</p> - </li> - </ul> - - <h4> - c. More advanced rendering - </h4> - - <p>Let us try to render transformed text now (for example through a - rotation). We can do this using <tt>FT_Set_Transform</tt>. Here is how - to do it:</p> - - <div class="pre"> - FT_GlyphSlot slot; - FT_Matrix matrix; <span class="comment">/* transformation matrix */</span> - FT_UInt glyph_index; - FT_Vector pen; <span class="comment">/* untransformed origin */</span> - int n; - - - ... initialize library ... - ... create face object ... - ... set character size ... - - slot = face->glyph; <span class="comment">/* a small shortcut */</span> - - <span class="comment">/* set up matrix */</span> - matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); - matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); - matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); - matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L ); - - <span class="comment">/* the pen position in 26.6 cartesian space coordinates */</span> - <span class="comment">/* start at (300,200) */</span> - pen.x = 300 * 64; - pen.y = ( my_target_height - 200 ) * 64; - - for ( n = 0; n < num_chars; n++ ) - { - <span class="comment">/* set transformation */</span> - FT_Set_Transform( face, &matrix, &pen ); - - <span class="comment">/* load glyph image into the slot (erase previous one) */</span> - error = FT_Load_Char( face, text[n], FT_LOAD_RENDER ); - if ( error ) - continue; <span class="comment">/* ignore errors */</span> - - <span class="comment">/* now, draw to our target surface (convert position) */</span> - my_draw_bitmap( &slot->bitmap, - slot->bitmap_left, - my_target_height - slot->bitmap_top ); - - <span class="comment">/* increment pen position */</span> - pen.x += slot->advance.x; - pen.y += slot->advance.y; - } - </div> +</div> <!-- id="wrapper" --> - <p>Some remarks:</p> - - <ul> - <li> - <p>We now use a vector of type <tt>FT_Vector</tt> to store the pen - position, with coordinates expressed as 1/64th of pixels, hence a - multiplication. The position is expressed in cartesian space.</p> - </li> - - <li> - <p>Glyph images are always loaded, transformed, and described in the - cartesian coordinate system in FreeType (which means that - increasing Y corresponds to upper scanlines), unlike the system - typically used for bitmaps (where the topmost scanline has - coordinate 0). We must thus convert between the two systems - when we define the pen position, and when we compute the topleft - position of the bitmap.</p> - </li> - - <li> - <p>We set the transformation on each glyph to indicate the rotation - matrix as well as a delta that will move the transformed image to - the current pen position (in cartesian space, not bitmap space).</p> - - <p>As a consequence, the values of <tt>bitmap_left</tt> and - <tt>bitmap_top</tt> correspond to the bitmap origin in target space - pixels. We thus don't add <tt>pen.x</tt> or <tt>pen.y</tt> to their - values when calling <tt>my_draw_bitmap</tt>.</p> - </li> - - <li> - <p>The advance width is always returned transformed, which is why it - can be directly added to the current pen position. Note that it is - <em>not</em> rounded this time.</p> - </li> - </ul> - - <p>A complete source code example can be found - <a href="example1.c">here</a>.</p> - - <p>It is important to note that, while this example is a bit more - complex than the previous one, it is strictly equivalent for the case - where the transform is the identity. Hence it can be used as a - replacement (but a more powerful one).</p> - - <p>It has however a few shortcomings that we will explain, and solve, in - the next part of this tutorial.</p> - - <hr> - - <h3> - Conclusion - </h3> - - <p>In this first section, you have learned the basics of - FreeType 2, as well as sufficient knowledge how to render rotated - text.</p> - - <p>The next section will dive into more details of the API in order - to let you access glyph metrics and images directly, as well as - how to deal with scaling, hinting, kerning, etc.</p> - - <p>The third section will discuss issues like modules, caching and a few - other advanced topics like how to use multiple size objects with a - single face. [This part hasn't been written yet.]</p> - -</td></tr> -</table> -</center> - -<h3 align=center> - <a href="step2.html">FreeType 2 Tutorial Step 2</a> -</h3> - -<p><font size=-3>Last update: 10-Apr-2013</font></p> +<div id="TOC-bottom"> +</div> </body> </html> diff --git a/lib/freetype/docs/tutorial/step2.html b/lib/freetype/docs/tutorial/step2.html index 2412b70d8..276bc37d0 100644 --- a/lib/freetype/docs/tutorial/step2.html +++ b/lib/freetype/docs/tutorial/step2.html @@ -1,1690 +1,1585 @@ -<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" -"http://www.w3.org/TR/html4/loose.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + <head> - <style type="text/css"> - body { font-family: Verdana, Geneva, Arial, Helvetica, serif; - color: #000000; - background: #FFFFFF; } - - p { text-align: justify; } - h1 { text-align: center; } - li { text-align: justify; } - td { padding: 0 0.5em 0 0.5em; } - - a:link { color: #0000EF; } - a:visited { color: #51188E; } - a:hover { color: #FF0000; } - - div.pre { font-family: monospace; - text-align: left; - white-space: pre; - color: blue; } - - div.example { font-family: monospace; - text-align: left; - white-space: pre; - color: purple; } - - span.comment { color: gray; } - </style> <meta http-equiv="Content-Type" - content="text/html; charset=iso-8859-1"> + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> <meta name="Author" content="David Turner"> - <title>FreeType 2 Tutorial</title> + + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + + <title>FreeType Tutorial / II</title> </head> -<body text="#000000" - bgcolor="#FFFFFF" - link="#0000EF" - vlink="#51188E" - alink="#FF0000"> -<h1 align=center> - FreeType 2 Tutorial<br> - Step 2 — managing glyphs -</h1> +<body> + +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> + Tutorial / II</h1> +</div> + + +<div id="wrapper"> + +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> + + + <!-- ************************************************** --> + + <div id="simple-glyph-loading"> + <h2>II. Managing Glyphs</h2> + + + <h3 id="section-1">1. Glyph Metrics</h3> + + <p>Glyph metrics are, as the name suggests, certain + distances associated with each glyph that describe how to + position this glyph while creating a text layout.</p> + + <p>There are usually two sets of metrics for a single glyph: + Those used to represent glyphs in horizontal text layouts + (Latin, Cyrillic, Arabic, Hebrew, etc.), and those used to + represent glyphs in vertical text layouts (Chinese, + Japanese, Korean, Mongolian, etc.).</p> + + <p>Note that only a few font formats provide vertical + metrics. You can test whether a given face object + contains them by using the + macro <a href="../reference/ft2-base_interface.html#FT_HAS_VERTICAL"><tt>FT_HAS_VERTICAL</tt></a>, + which returns true if appropriate.</p> + + <p>Individual glyph metrics can be accessed by first loading + the glyph in a face's glyph slot, then accessing them + through the <tt>face->glyph->metrics</tt> structure, + whose type + is <a href="../reference/ft2-base_interface.html#FT_Glyph_Metrics"><tt>FT_Glyph_Metrics</tt></a>. + We will discuss this in more detail below; for now, we + only note that it contains the following fields.</p> + + <dl> + <dt>width</dt> + <dd>This is the width of the glyph image's bounding box. + It is independent of the layout direction.</dd> + + <dt>height</dt> + <dd>This is the height of the glyph image's bounding box. + It is independent of the layout direction. Be careful + not to confuse it with the ‘height’ field in + the <a href="../reference/ft2-base_interface.html#FT_Size_Metrics"> + <tt>FT_Size_Metrics</tt></a> structure.</dd> + + <dt>horiBearingX</dt> + <dd>For <em>horizontal text layouts</em>, this is the + horizontal distance from the current cursor position to + the leftmost border of the glyph image's bounding + box.</dd> + + <dt>horiBearingY</dt> + <dd>For <em>horizontal text layouts</em>, this is the + vertical distance from the current cursor position (on + the baseline) to the topmost border of the glyph image's + bounding box.</dd> + + <dt>horiAdvance</dt> + <dd>For <em>horizontal text layouts</em>, this is the + horizontal distance to increment the pen position when + the glyph is drawn as part of a string of text.</dd> + + <dt>vertBearingX</dt> + <dd>For <em>vertical text layouts</em>, this is the + horizontal distance from the current cursor position to + the leftmost border of the glyph image's bounding + box.</dd> + + <dt>vertBearingY</dt> + <dd>For <em>vertical text layouts</em>, this is the + vertical distance from the current cursor position (on + the baseline) to the topmost border of the glyph image's + bounding box.</dd> + + <dt>vertAdvance</dt> + <dd>For <em>vertical text layouts</em>, this is the + vertical distance used to increment the pen position + when the glyph is drawn as part of a string of + text.</dd> + </dl> + + <p class="warning">As not all fonts do contain vertical + metrics, the values of <tt>vertBearingX</tt>, + <tt>vertBearingY</tt> and <tt>vertAdvance</tt> should not + be considered reliable if <tt>FT_HAS_VERTICAL</tt> returns + false.</p> + + <p>The following graphics illustrate the metrics more + clearly. In case a distance is directed, it is marked + with a single arrow, indicating a positive value. The + first image displays horizontal metrics, where the + baseline is the horizontal axis.</p> + + <div class="figure"> + <img src="metrics.png" + alt="horizontal layout" + width=388 + height=253> + </div> + + <p>For vertical text layouts, the baseline is vertical, + identical to the vertical axis. Contrary to all other + arrows, <tt>bearingX</tt> shows a negative value in this + image.</p> + + <div class="figure"> + <img src="metrics2.png" + alt="vertical layout" + width=294 + height=278> + </div> + + <p>The metrics found in <tt>face->glyph->metrics</tt> + are normally expressed in 26.6 pixel format (i.e., 1/64th + of pixels), unless you use the <tt>FT_LOAD_NO_SCALE</tt> + flag when calling <tt>FT_Load_Glyph</tt> + or <tt>FT_Load_Char</tt>. In this case, the metrics are + expressed in original font units.</p> + + <p>The glyph slot object has also a few other interesting + fields that eases a developer's work. You can access them + through <tt>face->glyph->xxx</tt>, + where <tt>xxx</tt> is one of the following fields.</p> + + <dl> + <dt>advance</dt> + <dd>This field is a <tt>FT_Vector</tt> that holds the + transformed advance for the glyph. That is useful when + you are using a transformation + through <tt>FT_Set_Transform</tt>, as shown in the + <a href="step1.html#transformed-text">rotated text + example</a> of part I. Other than that, its value + is by default (metrics.horiAdvance,0), unless you + specify <tt>FT_LOAD_VERTICAL</tt> when loading the glyph + image; it is then (0,metrics.vertAdvance).</dd> + + <dt>linearHoriAdvance</dt> + <dd>This field contains the linearly scaled value of the + glyph's horizontal advance width. Indeed, the value of + <tt>metrics.horiAdvance</tt> that is returned in the + glyph slot is normally rounded to integer pixel + coordinates (i.e., being a multiple of 64) by the + font driver that actually loads the glyph + image. <tt>linearHoriAdvance</tt> is a 16.16 + fixed-point number that gives the value of the original + glyph advance width in 1/65536th of pixels. It can be + use to perform pseudo device-independent text + layouts.</dd> + + <dt>linearVertAdvance</dt> + <dd>This is the similar to <tt>linearHoriAdvance</tt> but + for the glyph's vertical advance height. Its value is + only reliable if the font face contains vertical + metrics.</dd> + </dl> + + + <h3 id="section-2">2. Managing Glyph Images</h3> + + <p>The glyph image that is loaded in a glyph slot can be + converted into a bitmap, either by + using <tt>FT_LOAD_RENDER</tt> when loading it, or by + calling <a href="../reference/ft2-base_interface.html#FT_Render_Glyph"><tt>FT_Render_Glyph</tt></a>. + Each time you load a new glyph image, the previous one is + erased from the glyph slot.</p> + + <p>There are situations, however, where you may need to + extract this image from the glyph slot in order to cache + it within your application, and even perform additional + transformations and measures on it before converting it to + a bitmap.</p> + + <p>The FreeType 2 API has a specific extension that is + capable of dealing with glyph images in a flexible and + generic way. To use it, you first need to include + the <a href="../reference/ft2-header_file_macros.html#FT_GLYPH_H"><tt>FT_GLYPH_H</tt></a> + header file.</p> + + <pre> +#include FT_GLYPH_H</pre> + + <h4>a.Extracting the Glyph Image</h4> + + <p>You can extract a single glyph image very easily. Here + some code that shows how to do it.</p> + + <pre> +FT_Glyph glyph; <span class="comment">/* a handle to the glyph image */</span> + + +... +error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NORMAL ); +if ( error ) { ... } + +error = FT_Get_Glyph( face->glyph, &glyph ); +if ( error ) { ... }</pre> + + <p>The following steps are performed.</p> + + <ul> + <li>Create a variable named <tt>glyph</tt>, of + type <a href="../reference/ft2-glyph_management.html#FT_Glyph"><tt>FT_Glyph</tt></a>. + This is a handle (pointer) to an individual glyph + image.</li> + + <li>Load the glyph image in the normal way into the face's + glyph slot. We don't use <tt>FT_LOAD_RENDER</tt> + because we want to grab a scalable glyph image that we + can transform later on.</li> + + <li>Copy the glyph image from the slot into a + new <tt>FT_Glyph</tt> object by + calling <a href="../reference/ft2-glyph_management.html#FT_Get_Glyph"><tt>FT_Get_Glyph</tt></a>. + This function returns an error code and + sets <tt>glyph</tt>.</li> + </ul> + + <p>It is important to note that the extracted glyph is in + the same format as the original one that is still in the + slot. For example, if we are loading a glyph from a + TrueType font file, the glyph image is really a scalable + vector outline. You can access the + field <tt>glyph->format</tt> if you want to know + exactly how the glyph is modeled and stored.</p> + + <p>A new glyph object can be destroyed with a call + to <a href="../reference/ft2-glyph_management.html#FT_Done_Glyph"><tt>FT_Done_Glyph</tt></a>.</p> + + <p>The glyph object contains exactly one glyph image and a + 2D vector representing the glyph's advance in 16.16 + fixed-point coordinates. The latter can be accessed + directly as <tt>glyph->advance</tt></p> -<h3 align=center> - © 2009 David Turner - (<a href="mailto:david@freetype.org">david@freetype.org</a>)<br> - © 2009 The FreeType Development Team - (<a href="http://www.freetype.org">www.freetype.org</a>) -</h3> + <p class="warning">Note that unlike other FreeType objects, + the library doesn't keep a list of all allocated glyph + objects. This means you have to destroy them yourself + instead of relying on <tt>FT_Done_FreeType</tt> doing all + the clean-up.</p> -<center> -<table width="70%"> -<tr><td> + <h4>b. Transforming & Copying the Glyph Image</h4> - <hr> + <p>If the glyph image is scalable (i.e., + if <tt>glyph->format</tt> is not equal + to <tt>FT_GLYPH_FORMAT_BITMAP</tt>), it is possible to + transform the image anytime by a call + to <a href="../reference/ft2-glyph_management.html#FT_Glyph_Transform"><tt>FT_Glyph_Transform</tt></a>.</p> - <h2> - Introduction - </h2> + <p>You can also copy a single glyph image + with <a href="../reference/ft2-glyph_management.html#FT_Glyph_Copy"><tt>FT_Glyph_Copy</tt></a>.</p> - <p>This is the second section of the FreeType 2 tutorial. It - describes how to</p> + <pre> +FT_Glyph glyph, glyph2; +FT_Matrix matrix; +FT_Vector delta; - <ul> - <li>retrieve glyph metrics</li> - <li>easily manage glyph images</li> - <li>retrieve global metrics (including kerning)</li> - <li>render a simple string of text, with kerning</li> - <li>render a centered string of text (with kerning)</li> - <li>render a transformed string of text (with centering)</li> - <li>access metrics in design font units when needed, - and how to scale them to device space</li> - </ul> - - <hr> - - <h3> - 1. Glyph metrics - </h3> - - <p>Glyph metrics are, as their name suggests, certain distances - associated with each glyph in order to describe how to use it to layout - text.</p> - - <p>There are usually two sets of metrics for a single glyph: Those used - to layout the glyph in horizontal text layouts (Latin, Cyrillic, Arabic, - Hebrew, etc.), and those used to layout the glyph in vertical text - layouts (Chinese, Japanese, Korean, etc.).</p> - - <p>Note that only a few font formats provide vertical metrics. You can - test whether a given face object contains them by using the macro - <tt>FT_HAS_VERTICAL</tt>, which is true when appropriate.</p> - - <p>Individual glyph metrics can be accessed by first loading the glyph - in a face's glyph slot, then accessing them through the - <tt>face->glyph->metrics</tt> structure, whose type is <a - href="../reference/ft2-base_interface.html#FT_Glyph_Metrics"> - <tt>FT_Glyph_Metrics</tt></a>. We will discuss this in more detail - below; for now, we only note that it contains the following fields:</p> - - <center><table width="90%" cellpadding=5> - <tr valign=top> - <td> - <tt>width</tt> - </td> - <td> - <p>This is the width of the glyph image's bounding box. It is - independent of the layout direction.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>height</tt> - </td> - <td> - <p>This is the height of the glyph image's bounding box. It is - independent of the layout direction. Be careful not to confuse it - with the ‘height’ field in the <a - href="../reference/ft2-base_interface.html#FT_Size_Metrics"> - <tt>FT_Size_Metrics</tt></a> structure.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>horiBearingX</tt> - </td> - <td> - <p>For <em>horizontal text layouts</em>, this is the horizontal - distance from the current cursor position to the leftmost border of - the glyph image's bounding box.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>horiBearingY</tt> - </td> - <td> - <p>For <em>horizontal text layouts</em>, this is the vertical - distance from the current cursor position (on the baseline) to the - topmost border of the glyph image's bounding box.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>horiAdvance</tt> - </td> - <td> - <p>For <em>horizontal text layouts</em>, this is the horizontal - distance used to increment the pen position when the glyph is drawn - as part of a string of text.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>vertBearingX</tt> - </td> - <td> - <p>For <em>vertical text layouts</em>, this is the horizontal - distance from the current cursor position to the leftmost border of - the glyph image's bounding box.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>vertBearingY</tt> - </td> - <td> - <p>For <em>vertical text layouts</em>, this is the vertical distance - from the current cursor position (on the baseline) to the topmost - border of the glyph image's bounding box.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>vertAdvance</tt> - </td> - <td> - <p>For <em>vertical text layouts</em>, this is the vertical distance - used to increment the pen position when the glyph is drawn as part - of a string of text.</p> - </td> - </tr> - </table> - </center> - - <p><font color="red">NOTE: As not all fonts do contain vertical - metrics, the values of <tt>vertBearingX</tt>, <tt>vertBearingY</tt> and - <tt>vertAdvance</tt> should not be considered reliable when - <tt>FT_HAS_VERTICAL</tt> is false.</font></p> - - <p>The following graphics illustrate the metrics more clearly. First, - for horizontal metrics, where the baseline is the horizontal axis:</p> - - <center> - <img src="metrics.png" alt="horizontal layout" width=388 height=253> - </center> - - <p>For vertical text layouts, the baseline is vertical, identical to the - vertical axis:</p> - - <center> - <img src="metrics2.png" alt="vertical layout" width=294 height=278> - </center> - - <p>The metrics found in <tt>face->glyph->metrics</tt> are normally - expressed in 26.6 pixel format (i.e., 1/64th of pixels), unless you use - the <tt>FT_LOAD_NO_SCALE</tt> flag when calling <tt>FT_Load_Glyph</tt> - or <tt>FT_Load_Char</tt>. In this case, the metrics will be expressed - in original font units.</p> - - <p>The glyph slot object has also a few other interesting fields that - will ease a developer's work. You can access them through - <tt>face->glyph->xxx</tt>, where <tt>xxx</tt> is one of the - following fields:</p> - - <center><table width="90%" cellpadding=5> - <tr valign=top> - <td> - <tt>advance</tt> - </td> - <td> - <p>This field is a <tt>FT_Vector</tt> which holds the transformed - advance for the glyph. That is useful when you are using a transform - through <tt>FT_Set_Transform</tt>, as shown in the rotated text - example of section I. Other than that, its value is - by default (metrics.horiAdvance,0), unless you specify - <tt>FT_LOAD_VERTICAL</tt> when loading the glyph image; - it will then be (0,metrics.vertAdvance)</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>linearHoriAdvance</tt> - </td> - <td> - <p>This field contains the linearly scaled value of the glyph's - horizontal advance width. Indeed, the value of - <tt>metrics.horiAdvance</tt> that is returned in the glyph slot is - normally rounded to integer pixel coordinates (i.e., it will be a - multiple of 64) by the font driver used to load the glyph - image. <tt>linearHoriAdvance</tt> is a 16.16 fixed-point number - that gives the value of the original glyph advance width in - 1/65536th of pixels. It can be use to perform pseudo - device-independent text layouts.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>linearVertAdvance</tt> - </td> - <td> - <p>This is the similar to <tt>linearHoriAdvance</tt> but for the - glyph's vertical advance height. Its value is only reliable if the - font face contains vertical metrics.</p> - </td> - </tr> - </table> - </center> - - - <hr> - - <h3> - 2. Managing glyph images - </h3> - - <p>The glyph image that is loaded in a glyph slot can be converted into - a bitmap, either by using <tt>FT_LOAD_RENDER</tt> when loading it, or by - calling <tt>FT_Render_Glyph</tt>. Each time you load a new glyph image, - the previous one is erased from the glyph slot.</p> - - <p>There are situations, however, where you may need to extract this - image from the glyph slot in order to cache it within your application, - and even perform additional transformations and measures on it before - converting it to a bitmap.</p> - - <p>The FreeType 2 API has a specific extension which is capable of - dealing with glyph images in a flexible and generic way. To use it, you - first need to include the <a - href="../reference/ft2-header_file_macros.html#FT_GLYPH_H"> - <tt>FT_GLYPH_H</tt></a> header file, as in:</p> - - <div class="pre"> - #include FT_GLYPH_H - </div> - <p>We will now explain how to use the functions defined in this - file:</p> +... load glyph image in `glyph' ... - <h4> - a. Extracting the glyph image: - </h4> +<span class="comment">/* copy glyph to glyph2 */</span> - <p>You can extract a single glyph image very easily. Here some code - that shows how to do it:</p> +error = FT_Glyph_Copy( glyph, &glyph2 ); +if ( error ) { ... could not copy (out of memory) ... } - <div class="pre"> - FT_Glyph glyph; <span class="comment">/* a handle to the glyph image */</span> +<span class="comment">/* translate `glyph' */</span> +delta.x = -100 * 64; <span class="comment">/* coordinates are in 26.6 pixel format */</span> +delta.y = 50 * 64; - ... - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NORMAL ); - if ( error ) { ... } +FT_Glyph_Transform( glyph, 0, &delta ); - error = FT_Get_Glyph( face->glyph, &glyph ); - if ( error ) { ... } - </div> +<span class="comment">/* transform glyph2 (horizontal shear) */</span> - <p>As you see, we have:</p> +matrix.xx = 0x10000L; +matrix.xy = 0.12 * 0x10000L; +matrix.yx = 0; +matrix.yy = 0x10000L; - <ul> - <li> - <p>Created a variable, named <tt>glyph</tt>, of type <a - href="../reference/ft2-glyph_management.html#FT_Glyph"> - <tt>FT_Glyph</tt></a>. This is a handle (pointer) to an - individual glyph image.</p> - </li> +FT_Glyph_Transform( glyph2, &matrix, 0 );</pre> - <li> - <p>Loaded the glyph image normally in the face's glyph slot. We - did not use <tt>FT_LOAD_RENDER</tt> because we want to grab a - scalable glyph image, in order to later transform it.</p> - </li> + <p>Note that the 2×2 transformation matrix is always + applied to the 16.16 advance vector in the glyph; you thus + don't need to recompute it.</p> - <li> - <p>Copy the glyph image from the slot into a new <tt>FT_Glyph</tt> - object, by calling <a - href="../reference/ft2-glyph_management.html#FT_Get_Glyph"> - <tt>FT_Get_Glyph</tt></a>. This function returns an error code - and sets <tt>glyph</tt>.</p> - </li> - </ul> + <h4>c. Measuring the Glyph Image</h4> - <p>It is important to note that the extracted glyph is in the same - format as the original one that is still in the slot. For example, - if we are loading a glyph from a TrueType font file, the glyph image - will really be a scalable vector outline.</p> + <p>You can also retrieve the control (bounding) box of any + glyph image (scalable or not) through + the <a href="../reference/ft2-glyph_management.html#FT_Glyph_Get_CBox"><tt>FT_Glyph_Get_CBox</tt></a> + function.</p> - <p>You can access the field <tt>glyph->format</tt> if you want to - know exactly how the glyph is modeled and stored. A new glyph object - can be destroyed with a call to <a - href="../reference/ft2-glyph_management.html#FT_Done_Glyph"> - <tt>FT_Done_Glyph</tt></a>.</p> + <pre> +FT_BBox bbox; - <p>The glyph object contains exactly one glyph image and a 2D vector - representing the glyph's advance in 16.16 fixed-point coordinates. - The latter can be accessed directly as <tt>glyph->advance</tt></p> - <p><font color="red">Note that unlike other FreeType objects, the - library doesn't keep a list of all allocated glyph objects. This - means you have to destroy them yourself instead of relying on - <tt>FT_Done_FreeType</tt> doing all the clean-up.</font></p> +... +FT_Glyph_Get_CBox( glyph, <em>bbox_mode</em>, &bbox );</pre> + + <p>Coordinates are relative to the glyph origin (0,0), using + the y upwards convention. This function takes a + special argument, the <em>bbox mode</em>, to indicate how + box coordinates are expressed.</p> + + <p>If the glyph has been loaded + with <tt>FT_LOAD_NO_SCALE</tt>, <tt>bbox_mode</tt> must be + set to <tt>FT_GLYPH_BBOX_UNSCALED</tt> to get unscaled + font units in 26.6 pixel format. The + value <tt>FT_GLYPH_BBOX_SUBPIXELS</tt> is another name for + this constant.</p> + + <p>Note that the box's maximum coordinates are exclusive, + which means that you can always compute the width and + height of the glyph image (regardless of using integer or + 26.6 coordinates) with a simple subtraction.</p> + + <pre class="example"> +width = bbox.xMax - bbox.xMin; +height = bbox.yMax - bbox.yMin;</pre> + + <p>Note also that for 26.6 coordinates, if + <tt>FT_GLYPH_BBOX_GRIDFIT</tt> is used as the bbox mode, + the coordinates are also grid-fitted, which corresponds to + the following four lines.</p> + + <pre class="example"> +bbox.xMin = FLOOR( bbox.xMin ) +bbox.yMin = FLOOR( bbox.yMin ) +bbox.xMax = CEILING( bbox.xMax ) +bbox.yMax = CEILING( bbox.yMax )</pre> + + <p>To get the bbox in <em>integer</em> pixel coordinates, + set <tt>bbox_mode</tt> + to <tt>FT_GLYPH_BBOX_TRUNCATE</tt>.</p> - <h4> - b. Transforming & copying the glyph image - </h4> + <p>Finally, to get the bounding box in grid-fitted pixel + coordinates, set <tt>bbox_mode</tt> + to <tt>FT_GLYPH_BBOX_PIXELS</tt>.</p> - <p>If the glyph image is scalable (i.e., if <tt>glyph->format</tt> - is not equal to <tt>FT_GLYPH_FORMAT_BITMAP</tt>), it is possible to - transform the image anytime by a call to <a - href="../reference/ft2-glyph_management.html#FT_Glyph_Transform"> - <tt>FT_Glyph_Transform</tt></a>.</p> + <p>[Computing <em>exact</em> bounding boxes can be done with + function <a href="../reference/ft2-outline_processing.html#FT_Outline_Get_BBox"><tt>FT_Outline_Get_BBox</tt></a>, + at the cost of slower execution. You probably don't need + with the possible exception of rotated glyphs.]</p> + + <h4>d. Converting the Glyph Image to a Bitmap</h4> + + <p>You may need to convert the glyph object to a bitmap once + you have conveniently cached or transformed it. This can + be done easily with + the <a href="../reference/ft2-glyph_management.html"><tt>FT_Glyph_To_Bitmap</tt></a> + function, which handles any glyph object.</p> + + <pre> +FT_Vector origin; + + +origin.x = 32; <span class="comment">/* 1/2 pixel in 26.6 format */</span> +origin.y = 0; + +error = FT_Glyph_To_Bitmap( + &glyph, + <em>render_mode</em>, + &origin, + 1 ); <span class="comment">/* destroy original image == true */</span></pre> + + <p>Some notes.</p> + + <ul> + <li>The first parameter is the address of the source + glyph's handle. When the function is called, it reads + it to access the source glyph object. After the call, + the handle points to a <em>new</em> glyph object that + contains the rendered bitmap.</li> + + <li>The second parameter is a standard render mode to + specify what kind of bitmap we want. For example, it + can be <tt>FT_RENDER_MODE_DEFAULT</tt> for an 8-bit + anti-aliased pixmap, or <tt>FT_RENDER_MODE_MONO</tt> for + a 1-bit monochrome bitmap.</li> + + <li>The third parameter is a pointer to a two-dimensional + vector to translate the source glyph image before the + conversion. After the call, the source image is + translated back to its original position (and is thus + left unchanged). If you do not need to translate the + source glyph before rendering, set this pointer + to NULL.</li> + + <li>The last parameter is a boolean that indicates whether + the source glyph object should be destroyed by the + function. If false, the original glyph object is never + destroyed, even if its handle is lost (it is up to + client applications to keep it).</li> + </ul> + + <p>The new glyph object always contains a bitmap (if no + error is returned), and you must <em>typecast</em> its + handle to the <tt>FT_BitmapGlyph</tt> type in order to + access its content. This type is a sort of + ‘subclass’ of <tt>FT_Glyph</tt> that contains + additional fields + (see <a href="../reference/ft2-glyph_management.html#FT_BitmapGlyphRec"><tt>FT_BitmapGlyphRec</tt></a>).</p> + + <dl> + <dt>left</dt> + <dd>Just like the <tt>bitmap_left</tt> field of a glyph + slot, this is the horizontal distance from the glyph + origin (0,0) to the leftmost pixel of the glyph bitmap. + It is expressed in integer pixels.</dd> + + <dt>top</dt> + <dd>Just like the <tt>bitmap_top</tt> field of a glyph + slot, this is the vertical distance from the glyph + origin (0,0) to the topmost pixel of the glyph bitmap + (more precise, to the pixel just above the bitmap). + This distance is expressed in integer pixels, and is + positive for upwards y.</dd> + + <dt>bitmap</dt> + <dd>This is a bitmap descriptor for the glyph object, just + like the <tt>bitmap</tt> field in a glyph slot.</dd> + </dl> + + + <h3 id="section-3">3. Global Glyph Metrics</h3> + + <p>Unlike glyph metrics, global metrics are used to describe + distances and features of a whole font face. They can be + expressed either in 26.6 pixel format or in (unscaled) + font units for scalable formats.</p> + + <h4> a. Design global metrics</h4> + + <p>For scalable formats, all global metrics are expressed in + font units in order to be later scaled to the device + space, according to the rules described in the last + section of this tutorial part. You can access them + directly as fields of a <tt>FT_Face</tt> handle.</p> + + <p>However, you need to check that the font face's format is + scalable before using them. One can do it with + macro <tt>FT_IS_SCALABLE</tt>, which returns true when + appropriate.</p> + + <p>Here a table of the global design metrics for scalable + faces.</p> + + <dl> + <dt>units_per_EM</dt> + <dd>This is the size of the EM square for the font face. + It is used by scalable formats to scale design + coordinates to device pixels, as described in the last + section of this tutorial part. Its value usually is + 2048 (for TrueType) or 1000 (for Type 1 or CFF), + but other values are possible, too. It is set to 1 + for fixed-size formats like FNT, FON, PCF, or BDF.</dd> + + <dt>bbox</dt> + <dd>The global bounding box is defined as the smallest + rectangle that can enclose all the glyphs in a font + face.</dd> + + <dt>ascender</dt> + <dd>The ascender is the vertical distance from the + horizontal baseline to the highest + ‘character’ coordinate in a font face. + Unfortunately, font formats don't define the ascender in + a uniform way. For some formats, it represents the + ascent of all capital latin characters (without + accents), for others it is the ascent of the highest + accented character, and finally, other formats define it + as being equal to <tt>bbox.yMax</tt>.</dd> + + <dt>descender</dt> + <dd>The descender is the vertical distance from the + horizontal baseline to the lowest + ‘character’ coordinate in a font face. + Unfortunately, font formats don't define the descender + in a uniform way. For some formats, it represents the + descent of all capital latin characters (without + accents), for others it is the ascent of the lowest + accented character, and finally, other formats define it + as being equal to <tt>bbox.yMin</tt>. This field is + negative for values below the baseline.</dd> + + <dt>height</dt> + <dd>This field represents a <em>default line spacing</em> + (i.e., the baseline-to-baseline distance) when writing + text with this font. Note that it usually is larger + than the sum of the ascender and descender taken as + absolute values. There is also no guarantee that no + glyphs extend above or below subsequent baselines when + using this distance – think of it as a value the + designer of the font finds appropriate.</dd> + + <dt>max_advance_width</dt> + <dd>This field gives the maximum horizontal cursor advance + for all glyphs in the font. It can be used to quickly + compute the maximum advance width of a string of + text. <em>It doesn't correspond to the maximum glyph + image width!</em></dd> + + <dt>max_advance_height</dt> + <dd>Same as <tt>max_advance_width</tt> but for vertical + text layout.</dd> + + <dt>underline_position</dt> + <dd>When displaying or rendering underlined text, this + value corresponds to the vertical position, relative to + the baseline, of the underline bar's center. It is + negative if it is below the baseline.</dd> + + <dt>underline_thickness</dt> + <dd>When displaying or rendering underlined text, this + value corresponds to the vertical thickness of the + underline.</dd> + </dl> + + <p>Notice that the values of the ascender and the descender + are not reliable (due to various discrepancies in font + formats), unfortunately.</p> + + <h4>b. Scaled Global Metrics</h4> + + <p>Each size object also contains a scaled version of some + of the global metrics described above, to be directly + accessed through the <tt>face->size->metrics</tt> + structure (of type <a href="../reference/ft2-base_interface.html#FT_Size_Metrics"> + <tt>FT_Size_Metrics</tt></a>). <em>No rounding or + grid-fitting is performed for those values</em>. They are + also completely independent of any hinting process. In + other words, don't rely on them to get exact metrics at + the pixel level. They are expressed in 26.6 pixel + format.</p> + + <dl> + <dt>ascender</dt> + <dd>The scaled version of the original design + ascender.</dd> + + <dt>descender</dt> + <dd>The scaled version of the original design + descender.</dd> + + <dt>height</dt> + <dd> + <p>The scaled version of the original design text height + (the vertical distance from one baseline to the next). + This is probably the only field you should really use + in this structure.</p> + + <p>Be careful not to confuse it with the + ‘height’ field in + the <a href="../reference/ft2-base_interface.html#FT_Glyph_Metrics"><tt>FT_Glyph_Metrics</tt></a> + structure.</p> + </dd> + + <dt>max_advance</dt> + <dd>The scaled version of the original design maximum + advance.</dd> + </dl> + + <p>Note that the <tt>face->size->metrics</tt> + structure contains other fields that are used to scale + design coordinates to device space. They are described in + the last section.</p> + + <h4>c. Kerning</h4> + + <p>Kerning is the process of adjusting the position of two + subsequent glyph images in a string of text in order to + improve the general appearance of text. For example, if a + glyph for an uppercase ‘A’ is followed by a + glyph for an uppercase ‘V’, the space between + the two glyphs can be slightly reduced to avoid extra + ‘diagonal whitespace’.</p> + + <p>Note that in theory kerning can happen both in the + horizontal and vertical direction between two glyphs; + however, it only happens in a single direction in nearly + all cases.</p> + + <p>Not all font formats contain kerning information, and not + all kerning formats are supported by FreeType; in + particular, for TrueType fonts, the API can only access + kerning via the ‘kern’ + table. <span class="important">OpenType kerning via the + ‘GPOS’ table is not supported!</span> You + need a higher-level library + like <a href="http://www.harfbuzz.org">HarfBuzz</a>, + <a href="http://www.pango.org">Pango</a>, + or <a href="http://www.icu-project.org">ICU</a>, since + GPOS kerning requires contextual string handling.</p> + + <p>Sometimes, the font file is associated with an additional + file that contains various glyph metrics, including + kerning, but no glyph images. A good example is the + Type 1 format where glyph images are stored in files + with extension <tt>.pfa</tt> or <tt>.pfb</tt>, while + kerning metrics can be found in files with extension + <tt>.afm</tt> or <tt>.pfm</tt>.</p> + + <p>FreeType 2 allows you to deal with this, by + providing + the <a href="../reference/ft2-base_interface.html#FT_Attach_File"><tt>FT_Attach_File</tt></a> + and <a href="../reference/ft2-base_interface.html#FT_Attach_Stream"><tt>FT_Attach_Stream</tt></A> + APIs. Both functions are used to load additional metrics + into a face object by reading them from an additional + format-specific file. Here an example, opening a + Type 1 font.</p> + + <pre> +error = FT_New_Face( library, "/usr/share/fonts/cour.pfb", + 0, &face ); +if ( error ) { ... } + +error = FT_Attach_File( face, "/usr/share/fonts/cour.afm" ); +if ( error ) +{ ... could not read kerning and additional metrics ... }</pre> + + <p>Note that <tt>FT_Attach_Stream</tt> is similar to + <tt>FT_Attach_File</tt> except that it doesn't take a + C string to name the extra file but + an <a href="../reference/ft2-system_interface.html#FT_StreamRec"><tt>FT_Stream</tt></a> + handle. Also, <em>reading a metrics file is in no way + mandatory</em>.</p> + + <p>Finally, the file attachment APIs are very generic and + can be used to load any kind of extra information for a + given face. The nature of the additional content is + entirely font format specific.</p> + + <p>FreeType 2 allows you to retrieve the kerning + information between two glyphs through + the <a href="../reference/ft2-base_interface.html#FT_Get_Kerning"><tt>FT_Get_Kerning</tt></a> + function.</p> + + <pre> +FT_Vector kerning; + + +... +error = FT_Get_Kerning( face, <span class="comment">/* handle to face object */</span> + left, <span class="comment">/* left glyph index */</span> + right, <span class="comment">/* right glyph index */</span> + <em>kerning_mode</em>, <span class="comment">/* kerning mode */</span> + &kerning ); <span class="comment">/* target vector */</span></pre> + + <p>This function takes a handle to a face object, the + indices of the left and right glyph for which the kerning + value is desired, an integer, called the <em>kerning + mode</em>, and a pointer to a destination vector that + receives the corresponding distances.</p> + + <p>The kerning mode is very similar to the <em>bbox + mode</em> described in a previous section. It is a + enumeration that indicates how the kerning distances are + expressed in the target vector.</p> + + <p>The default value is <tt>FT_KERNING_DEFAULT</tt>, which + has value 0. It corresponds to kerning distances + expressed in 26.6 grid-fitted pixels (which means that the + values are multiples of 64). For scalable formats, this + means that the design kerning distance is scaled, then + rounded.</p> + + <p>The value <tt>FT_KERNING_UNFITTED</tt> corresponds to + kerning distances expressed in 26.6 unfitted pixels (i.e., + that do not correspond to integer coordinates). It is the + design kerning distance that is scaled without + rounding.</p> + + <p>Finally, the value <tt>FT_KERNING_UNSCALED</tt> indicates + to return the design kerning distance, expressed in font + units. You can later scale it to the device space using + the computations explained in the last section of this + part.</p> + + <p>Note that the ‘left’ and ‘right’ + positions correspond to the <em>visual order</em> of the + glyphs in the string of text. This is important for + bidirectional or right-to-left text.</p> + + + <h3 id="section-4">4. Simple Text Rendering: Kerning and Centering</h3> + + <p>In order to show off what we have just learned, we now + demonstrate how to modify + the <a href="step1.html#basic-code">example code</a> that + was provided in part I to render a string of text, + and enhance it to support kerning and delayed + rendering.</p> + + <h4>a. Kerning Support</h4> + + <p>Adding support for kerning to our code is trivial, as + long as we consider that we are still dealing with a + left-to-right script like Latin. We simply need to + retrieve the kerning distance between two glyphs in order + to alter the pen position appropriately.</p> + + <pre> +FT_GlyphSlot slot = face->glyph; <span class="comment">/* a small shortcut */</span> +FT_UInt glyph_index; +FT_Bool use_kerning; +FT_UInt previous; +int pen_x, pen_y, n; + + +... initialize library ... +... create face object ... +... set character size ... + +pen_x = 300; +pen_y = 200; + +use_kerning = FT_HAS_KERNING( face ); +previous = 0; + +for ( n = 0; n < num_chars; n++ ) +{ + <span class="comment">/* convert character code to glyph index */</span> + glyph_index = FT_Get_Char_Index( face, text[n] ); + + <span class="comment">/* retrieve kerning distance and move pen position */</span> + if ( use_kerning && previous && glyph_index ) + { + FT_Vector delta; - <p>You can also copy a single glyph image with <a - href="../reference/ft2-glyph_management.html#FT_Glyph_Copy"> - <tt>FT_Glyph_Copy</tt></a>. Here is some example code:</p> - <div class="pre"> - FT_Glyph glyph, glyph2; - FT_Matrix matrix; - FT_Vector delta; + FT_Get_Kerning( face, previous, glyph_index, + FT_KERNING_DEFAULT, &delta ); + pen_x += delta.x >> 6; + } - ... load glyph image in `glyph' ... + <span class="comment">/* load glyph image into the slot (erase previous one) */</span> + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_RENDER ); + if ( error ) + continue; <span class="comment">/* ignore errors */</span> + + <span class="comment">/* now draw to our target surface */</span> + my_draw_bitmap( &slot->bitmap, + pen_x + slot->bitmap_left, + pen_y - slot->bitmap_top ); + + <span class="comment">/* increment pen position */</span> + pen_x += slot->advance.x >> 6; + + <span class="comment">/* record current glyph index */</span> + previous = glyph_index; +}</pre> + + <p>We are done. Some notes.</p> + + <ul> + <li>As kerning is determined by glyph indices, we need + to explicitly convert our character codes into glyph + indices, then later call <tt>FT_Load_Glyph</tt> instead + of <tt>FT_Load_Char</tt>.</li> + + <li>We use a boolean named <tt>use_kerning</tt>, which is + set to the result of the macro <tt>FT_HAS_KERNING</tt>. + It is certainly faster not to + call <tt>FT_Get_Kerning</tt> when we know that the font + face does not contain kerning information.</li> + + <li>We move the position of the pen <em>before</em> a new + glyph is drawn.</li> + + <li>We initialize the variable <tt>previous</tt> with the + value 0, which always corresponds to the + ‘missing glyph’ (also + called <tt>.notdef</tt> in the PostScript world). There + is never any kerning distance associated with this + glyph.</li> + + <li>We do not check the error code returned by + <tt>FT_Get_Kerning</tt>. This is because the function + always sets the content of <tt>delta</tt> to (0,0) if + an error occurs.</li> + </ul> + + <h4>b. Centering</h4> + + <p>Our code begins to become interesting but it is still a + bit too simple for normal use. For example, the position + of the pen is determined before we do the rendering; + normally, you would rather determine the layout of the + text and measure it before computing its final position + (centering, etc.), or perform things like + word-wrapping.</p> + + <p>Let us now decompose our text rendering function into two + distinct but successive parts: The first one positions + individual glyph images on the baseline, while the second + one renders the glyphs. As we will see, this has many + advantages.</p> + + <p>We thus start by storing individual glyph images, as well + as their position on the baseline.</p> + + <pre> +FT_GlyphSlot slot = face->glyph; <span class="comment">/* a small shortcut */</span> +FT_UInt glyph_index; +FT_Bool use_kerning; +FT_UInt previous; +int pen_x, pen_y, n; + +FT_Glyph glyphs[MAX_GLYPHS]; <span class="comment">/* glyph image */</span> +FT_Vector pos [MAX_GLYPHS]; <span class="comment">/* glyph position */</span> +FT_UInt num_glyphs; + + +... initialize library ... +... create face object ... +... set character size ... + +pen_x = 0; <span class="comment">/* start at (0,0) */</span> +pen_y = 0; + +num_glyphs = 0; +use_kerning = FT_HAS_KERNING( face ); +previous = 0; + +for ( n = 0; n < num_chars; n++ ) +{ + <span class="comment">/* convert character code to glyph index */</span> + glyph_index = FT_Get_Char_Index( face, text[n] ); + + <span class="comment">/* retrieve kerning distance and move pen position */</span> + if ( use_kerning && previous && glyph_index ) + { + FT_Vector delta; - <span class="comment">/* copy glyph to glyph2 */</span> - error = FT_Glyph_Copy( glyph, &glyph2 ); - if ( error ) { ... could not copy (out of memory) ... } + FT_Get_Kerning( face, previous, glyph_index, + FT_KERNING_DEFAULT, &delta ); - <span class="comment">/* translate `glyph' */</span> + pen_x += delta.x >> 6; + } - delta.x = -100 * 64; <span class="comment">/* coordinates are in 26.6 pixel format */</span> - delta.y = 50 * 64; + <span class="comment">/* store current pen position */</span> + pos[num_glyphs].x = pen_x; + pos[num_glyphs].y = pen_y; - FT_Glyph_Transform( glyph, 0, &delta ); + <span class="comment">/* load glyph image into the slot without rendering */</span> + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); + if ( error ) + continue; <span class="comment">/* ignore errors, jump to next glyph */</span> - <span class="comment">/* transform glyph2 (horizontal shear) */</span> + <span class="comment">/* extract glyph image and store it in our table */</span> + error = FT_Get_Glyph( face->glyph, &glyphs[num_glyphs] ); + if ( error ) + continue; <span class="comment">/* ignore errors, jump to next glyph */</span> - matrix.xx = 0x10000L; - matrix.xy = 0.12 * 0x10000L; - matrix.yx = 0; - matrix.yy = 0x10000L; + <span class="comment">/* increment pen position */</span> + pen_x += slot->advance.x >> 6; - FT_Glyph_Transform( glyph2, &matrix, 0 ); - </div> + <span class="comment">/* record current glyph index */</span> + previous = glyph_index; - <p>Note that the 2×2 transform matrix is always applied to the - 16.16 advance vector in the glyph; you thus don't need to recompute - it.</p> + <span class="comment">/* increment number of glyphs */</span> + num_glyphs++; +}</pre> - <h4> - c. Measuring the glyph image - </h4> + <p>This is a very slight variation of our previous code; we + extract each glyph image from the slot, then store it, + along with the corresponding position, in our tables.</p> - <p>You can also retrieve the control (bounding) box of any glyph image - (scalable or not) through the <a - href="../reference/ft2-glyph_management.html#FT_Glyph_Get_CBox"> - <tt>FT_Glyph_Get_CBox</tt></a> function, as in:</p> + <p>Note also that <tt>pen_x</tt> contains the total advance + for the string of text. We can now compute the bounding + box of the text string with a simple function.</p> - <div class="pre"> + <pre> +void compute_string_bbox( FT_BBox *abbox ) +{ FT_BBox bbox; + FT_BBox glyph_bbox; - ... - FT_Glyph_Get_CBox( glyph, <em>bbox_mode</em>, &bbox ); - </div> - - <p>Coordinates are relative to the glyph origin (0,0), using the - y upwards convention. This function takes a special argument, - the <em>bbox mode</em>, to indicate how box coordinates are - expressed.</p> - - <p>If the glyph has been loaded with <tt>FT_LOAD_NO_SCALE</tt>, - <tt>bbox_mode</tt> must be set to <tt>FT_GLYPH_BBOX_UNSCALED</tt> to - get unscaled font units in 26.6 pixel format. The value - <tt>FT_GLYPH_BBOX_SUBPIXELS</tt> is another name for this - constant.</p> - - <p>Note that the box's maximum coordinates are exclusive, which means - that you can always compute the width and height of the glyph image, - be in in integer or 26.6 pixels, with:</p> - - <div class="pre"> - width = bbox.xMax - bbox.xMin; - height = bbox.yMax - bbox.yMin; - </div> - - <p>Note also that for 26.6 coordinates, if - <tt>FT_GLYPH_BBOX_GRIDFIT</tt> is used as the bbox mode, the - coordinates will also be grid-fitted, which corresponds to</p> - - <div class="pre"> - bbox.xMin = FLOOR( bbox.xMin ) - bbox.yMin = FLOOR( bbox.yMin ) - bbox.xMax = CEILING( bbox.xMax ) - bbox.yMax = CEILING( bbox.yMax ) - </div> - - <p>To get the bbox in <em>integer</em> pixel coordinates, set - <tt>bbox_mode</tt> to <tt>FT_GLYPH_BBOX_TRUNCATE</tt>.</p> - - <p>Finally, to get the bounding box in grid-fitted pixel coordinates, - set <tt>bbox_mode</tt> to <tt>FT_GLYPH_BBOX_PIXELS</tt>. - - <h4> - d. Converting the glyph image to a bitmap - </h4> + <span class="comment">/* initialize string bbox to "empty" values */</span> + bbox.xMin = bbox.yMin = 32000; + bbox.xMax = bbox.yMax = -32000; - <p>You may need to convert the glyph object to a bitmap once you have - conveniently cached or transformed it. This can be done easily with - the <a href="../reference/ft2-glyph_management.html"> - <tt>FT_Glyph_To_Bitmap</tt></a> function. It is in charge of - converting any glyph object into a bitmap, as in:</p> - - <div class="pre"> - FT_Vector origin; - - - origin.x = 32; <span class="comment">/* 1/2 pixel in 26.6 format */</span> - origin.y = 0; - - error = FT_Glyph_To_Bitmap( - &glyph, - <em>render_mode</em>, - &origin, - 1 ); <span class="comment">/* destroy original image == true */</span> - </div> - - <p>Some notes:</p> - - <ul> - <li> - <p>The first parameter is the address of the source glyph's - handle. When the function is called, it reads its to access the - source glyph object. After the call, the handle will point to a - <em>new</em> glyph object that contains the rendered bitmap.</p> - </li> - - <li> - <p>The second parameter is a standard render mode, that is used to - specify what kind of bitmap we want. It can be - <tt>FT_RENDER_MODE_DEFAULT</tt> for an 8-bit anti-aliased pixmap, - or <tt>FT_RENDER_MODE_MONO</tt> for a 1-bit monochrome bitmap.</p> - </li> - - <li> - <p>The third parameter is a pointer to a two-dimensional vector - that is used to translate the source glyph image before the - conversion. Note that the source image will be translated back to - its original position (and will thus be left unchanged) after the - call. If you do not need to translate the source glyph before - rendering, set this pointer to 0.</p> - </li> - - <li> - <p>The last parameter is a boolean that indicates whether the - source glyph object should be destroyed by the function. If - false, the original glyph object is never destroyed, even if its - handle is lost (it is up to client applications to keep it).</p> - </li> - </ul> - - <p>The new glyph object always contains a bitmap (if no error is - returned), and you must <em>typecast</em> its handle to the - <tt>FT_BitmapGlyph</tt> type in order to access its content. This - type is a sort of ‘subclass’ of <tt>FT_Glyph</tt> that - contains additional fields (see <a - href="../reference/ft2-glyph_management.html#FT_BitmapGlyphRec"> - <tt>FT_BitmapGlyphRec</tt></a>):</p> - - <center> - <table width="80%" cellpadding=5> - <tr valign=top> - <td> - <tt>left</tt> - </td> - <td> - <p>Just like the <tt>bitmap_left</tt> field of a glyph slot, this - is the horizontal distance from the glyph origin (0,0) to the - leftmost pixel of the glyph bitmap. It is expressed in integer - pixels.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>top</tt> - </td> - <td> - <p>Just like the <tt>bitmap_top</tt> field of a glyph slot, this - is the vertical distance from the glyph origin (0,0) to the - topmost pixel of the glyph bitmap (more precise, to the pixel just - above the bitmap). This distance is expressed in integer pixels, - and is positive for upwards y.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>bitmap</tt> - </td> - <td> - <p>This is a bitmap descriptor for the glyph object, just like the - <tt>bitmap</tt> field in a glyph slot.</p> - </td> - </tr> - </table> - </center> - - <hr> - - <h3> - 3. Global glyph metrics - </h3> - - <p>Unlike glyph metrics, global metrics are used to describe distances - and features of a whole font face. They can be expressed either in 26.6 - pixel format or in design ‘font units’ for scalable - formats.</p> - - <h4> - a. Design global metrics - </h4> - - <p>For scalable formats, all global metrics are expressed in font - units in order to be later scaled to the device space, according to - the rules described in the last chapter of this section of the - tutorial. You can access them directly as simple fields of a - <tt>FT_Face</tt> handle.</p> - - <p>However, you need to check that the font face's format is scalable - before using them. One can do it by using the macro - <tt>FT_IS_SCALABLE</tt> which returns true when appropriate.</p> - - <p>In this case, you can access the global design metrics as:</p> - - <center> - <table width="90%" cellpadding=5> - <tr valign=top> - <td> - <tt>units_per_EM</tt> - </td> - <td> - <p>This is the size of the EM square for the font face. It is - used by scalable formats to scale design coordinates to device - pixels, as described in the last chapter of this section. Its - value usually is 2048 (for TrueType) or 1000 (for Type 1), - but others are possible too. It is set to 1 for fixed-size - formats like FNT/FON/PCF/BDF.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>bbox</tt> - </td> - <td> - <p>The global bounding box is defined as the largest rectangle - that can enclose all the glyphs in a font face.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>ascender</tt> - </td> - <td> - <p>The ascender is the vertical distance from the horizontal - baseline to the highest ‘character’ coordinate in a - font face. Unfortunately, font formats define the ascender - differently. For some, it represents the ascent of all capital - latin characters (without accents), for others it is the ascent of - the highest accented character, and finally, other formats define - it as being equal to <tt>bbox.yMax</tt>.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>descender</tt> - </td> - <td> - <p>The descender is the vertical distance from the horizontal - baseline to the lowest ‘character’ coordinate in a - font face. Unfortunately, font formats define the descender - differently. For some, it represents the descent of all capital - latin characters (without accents), for others it is the ascent of - the lowest accented character, and finally, other formats define - it as being equal to <tt>bbox.yMin</tt>. This field is - negative for values below the baseline.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>height</tt> - </td> - <td> - <p>This field is simply used to compute a <i>default</i> line - spacing (i.e., the baseline-to-baseline distance) when writing - text with this font. Note that it usually is larger than the sum - of the ascender and descender taken as absolute values. There is - also no guarantee that no glyphs extend above or below subsequent - baselines when using this distance.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>max_advance_width</tt> - </td> - <td> - <p>This field gives the maximum horizontal cursor advance for all - glyphs in the font. It can be used to quickly compute the maximum - advance width of a string of text. <em>It doesn't correspond to - the maximum glyph image width!</em></p> - </td> - </tr> - <tr valign=top> - <td> - <tt>max_advance_height</tt> - </td> - <td> - <p>Same as <tt>max_advance_width</tt> but for vertical text - layout.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>underline_position</tt> - </td> - <td> - <p>When displaying or rendering underlined text, this value - corresponds to the vertical position, relative to the baseline, of - the underline bar's center. It is negative if it is below the - baseline.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>underline_thickness</tt> - </td> - <td> - <p>When displaying or rendering underlined text, this value - corresponds to the vertical thickness of the underline.</p> - </td> - </tr> - </table> - </center> - - <p>Notice how, unfortunately, the values of the ascender and the - descender are not reliable (due to various discrepancies in font - formats).</p> - - <h4> - b. Scaled global metrics - </h4> - - <p>Each size object also contains a scaled versions of some of the - global metrics described above. They can be accessed directly through - the <tt>face->size->metrics</tt> structure.</p> - - <p>Note that these values correspond to scaled versions of the design - global metrics, <em>with no rounding or grid-fitting performed</em>. - They are also completely independent of any hinting process. In other - words, don't rely on them to get exact metrics at the pixel level. - They are expressed in 26.6 pixel format.</p> - - <center> - <table width="80%" cellpadding=5> - <tr valign=top> - <td> - <tt>ascender</tt> - </td> - <td> - <p>The scaled version of the original design ascender.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>descender</tt> - </td> - <td> - <p>The scaled version of the original design descender.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>height</tt> - </td> - <td> - <p>The scaled version of the original design text height (the - vertical distance from one baseline to the next). This is - probably the only field you should really use in this - structure.</p> - - <p>Be careful not to confuse it with the ‘height’ - field in the <a - href="../reference/ft2-base_interface.html#FT_Glyph_Metrics"> - <tt>FT_Glyph_Metrics</tt></a> structure.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>max_advance</tt> - </td> - <td> - <p>The scaled version of the original design max advance.</p> - </td> - </tr> - </table> - </center> - - <p>Note that the <tt>face->size->metrics</tt> structure contains - other fields that are used to scale design coordinates to device - space. They are described in the last chapter.</p> - - <h4> - c. Kerning - </h4> - - <p>Kerning is the process of adjusting the position of two subsequent - glyph images in a string of text in order to improve the general - appearance of text. Basically, it means that when the glyph for an - ‘A’ is followed by the glyph for a ‘V’, the - space between them can be slightly reduced to avoid extra - ‘diagonal whitespace’.</p> - - <p>Note that in theory kerning can happen both in the horizontal and - vertical direction between two glyphs; however, it only happens in the - horizontal direction in nearly all cases except really extreme - ones.</p> - - <p>Not all font formats contain kerning information, and not all - kerning formats are supported by FreeType; in particular, for TrueType - fonts, the API can only access kerning via the ‘kern’ - table; <b>OpenType kerning via the ‘GPOS’ table is not - supported.</b> You need a higher-level library like <a - href="http://www.pango.org">Pango</a> or <a - href="http://www.icu-project.org">ICU</a> to handle that.</p> - - <p>Sometimes, the font file is associated with an additional file that - contains various glyph metrics, including kerning, but no glyph - images. A good example is the Type 1 format where glyph images - are stored in a file with extension <tt>.pfa</tt> or <tt>.pfb</tt>, - and where kerning metrics can be found in a file with extension - <tt>.afm</tt> or <tt>.pfm</tt>.</p> - - <p>FreeType 2 allows you to deal with this, by providing the <a - href="../reference/ft2-base_interface.html#FT_Attach_File"> - <tt>FT_Attach_File</tt></a> and <a - href="../reference/ft2-base_interface.html#FT_Attach_Stream"> - <tt>FT_Attach_Stream</tt></A> APIs. Both functions are used to load - additional metrics into a face object by reading them from an - additional format-specific file. For example, you could open a - Type 1 font by doing the following:</p> - - <div class="pre"> - error = FT_New_Face( library, "/usr/shared/fonts/cour.pfb", - 0, &face ); - if ( error ) { ... } - - error = FT_Attach_File( face, "/usr/shared/fonts/cour.afm" ); - if ( error ) - { ... could not read kerning and additional metrics ... } - </div> - - <p>Note that <tt>FT_Attach_Stream</tt> is similar to - <tt>FT_Attach_File</tt> except that it doesn't take a C string to - name the extra file but a <tt>FT_Stream</tt> handle. Also, - <em>reading a metrics file is in no way mandatory</em>.</p> - - <p>Finally, the file attachment APIs are very generic and can be used - to load any kind of extra information for a given face. The nature of - the additional content is entirely font format specific.</p> - - <p>FreeType 2 allows you to retrieve the kerning information for - two glyphs through the <tt>FT_Get_Kerning</tt> function, whose - interface looks like:</p> - - <div class="pre"> - FT_Vector kerning; - - - ... - error = FT_Get_Kerning( face, <span class="comment">/* handle to face object */</span> - left, <span class="comment">/* left glyph index */</span> - right, <span class="comment">/* right glyph index */</span> - <em>kerning_mode</em>, <span class="comment">/* kerning mode */</span> - &kerning ); <span class="comment">/* target vector */</span> - </div> - - <p>As you see, the function takes a handle to a face object, the - indices of the left and right glyph for which the kerning value is - desired, as well as an integer, called the <em>kerning mode</em>, and - a pointer to a destination vector that receives the corresponding - distances.</p> - - <p>The kerning mode is very similar to the <em>bbox mode</em> - described in a previous chapter. It is a enumeration that indicates - how the kerning distances are expressed in the target vector.</p> - - <p>The default value is <tt>FT_KERNING_DEFAULT</tt> which has - value 0. It corresponds to kerning distances expressed in 26.6 - grid-fitted pixels (which means that the values are multiples of 64). - For scalable formats, this means that the design kerning distance is - scaled, then rounded.</p> - - <p>The value <tt>FT_KERNING_UNFITTED</tt> corresponds to kerning - distances expressed in 26.6 unfitted pixels (i.e., that do not - correspond to integer coordinates). It is the design kerning distance - that is scaled without rounding.</p> - - <p>Finally, the value <tt>FT_KERNING_UNSCALED</tt> is used to return - the design kerning distance, expressed in font units. You can later - scale it to the device space using the computations explained in the - last chapter of this section.</p> - - <p>Note that the ‘left’ and ‘right’ positions - correspond to the <em>visual order</em> of the glyphs in the string of - text. This is important for bidirectional text, or simply when - writing right-to-left text.</p> - - <hr> - - <h3> - 4. Simple text rendering: kerning + centering - </h3> - - <p>In order to show off what we just learned, we will now demonstrate - how to modify the example code that was provided in section I to - render a string of text, and enhance it to support kerning and delayed - rendering.</p> - - <h4> - a. Kerning support - </h4> - - <p>Adding support for kerning to our code is trivial, as long as we - consider that we are still dealing with a left-to-right script like - Latin. We simply need to retrieve the kerning distance between two - glyphs in order to alter the pen position appropriately. The code - looks like:</p> - - <div class="pre"> - FT_GlyphSlot slot = face->glyph; <span class="comment">/* a small shortcut */</span> - FT_UInt glyph_index; - FT_Bool use_kerning; - FT_UInt previous; - int pen_x, pen_y, n; - - - ... initialize library ... - ... create face object ... - ... set character size ... - - pen_x = 300; - pen_y = 200; - - use_kerning = FT_HAS_KERNING( face ); - previous = 0; - - for ( n = 0; n < num_chars; n++ ) + <span class="comment">/* for each glyph image, compute its bounding box, */</span> + <span class="comment">/* translate it, and grow the string bbox */</span> + for ( n = 0; n < num_glyphs; n++ ) { - <span class="comment">/* convert character code to glyph index */</span> - glyph_index = FT_Get_Char_Index( face, text[n] ); - - <span class="comment">/* retrieve kerning distance and move pen position */</span> - if ( use_kerning && previous && glyph_index ) - { - FT_Vector delta; - - - FT_Get_Kerning( face, previous, glyph_index, - FT_KERNING_DEFAULT, &delta ); + FT_Glyph_Get_CBox( glyphs[n], ft_glyph_bbox_pixels, + &glyph_bbox ); - pen_x += delta.x >> 6; - } + glyph_bbox.xMin += pos[n].x; + glyph_bbox.xMax += pos[n].x; + glyph_bbox.yMin += pos[n].y; + glyph_bbox.yMax += pos[n].y; - <span class="comment">/* load glyph image into the slot (erase previous one) */</span> - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_RENDER ); - if ( error ) - continue; <span class="comment">/* ignore errors */</span> + if ( glyph_bbox.xMin < bbox.xMin ) + bbox.xMin = glyph_bbox.xMin; - <span class="comment">/* now draw to our target surface */</span> - my_draw_bitmap( &slot->bitmap, - pen_x + slot->bitmap_left, - pen_y - slot->bitmap_top ); + if ( glyph_bbox.yMin < bbox.yMin ) + bbox.yMin = glyph_bbox.yMin; - <span class="comment">/* increment pen position */</span> - pen_x += slot->advance.x >> 6; + if ( glyph_bbox.xMax > bbox.xMax ) + bbox.xMax = glyph_bbox.xMax; - <span class="comment">/* record current glyph index */</span> - previous = glyph_index; + if ( glyph_bbox.yMax > bbox.yMax ) + bbox.yMax = glyph_bbox.yMax; } - </div> - <p>We are done. Some notes:</p> - - <ul> - <li> - - <p>As kerning is determined from glyph indices, we need to - explicitly convert our character codes into glyph indices, then - later call <tt>FT_Load_Glyph</tt> instead of - <tt>FT_Load_Char</tt>.</p> - </li> - - <li> - <p>We use a boolean named <tt>use_kerning</tt> which is set with - the result of the macro <tt>FT_HAS_KERNING</tt>. It is certainly - faster not to call <tt>FT_Get_Kerning</tt> when we know that the - font face does not contain kerning information.</p> - </li> - - <li> - <p>We move the position of the pen <em>before</em> a new glyph is - drawn.</p> - </li> - - <li> - <p>We initialize the variable <tt>previous</tt> with the - value 0, which always corresponds to the ‘missing - glyph’ (also called <tt>.notdef</tt> in the Postscript - world). There is never any kerning distance associated with this - glyph.</p> - </li> - - <li> - <p>We do not check the error code returned by - <tt>FT_Get_Kerning</tt>. This is because the function always sets - the content of <tt>delta</tt> to (0,0) when an error occurs.</p> - </li> - </ul> - - <h4> - b. Centering - </h4> - - <p>Our code begins to become interesting but it is still a bit too - simple for normal use. For example, the position of the pen is - determined before we do the rendering; normally, you would rather - layout the text and measure it before computing its final position - (centering, etc.) or perform things like word-wrapping.</p> - - <p>Let us now decompose our text rendering function into two distinct - but successive parts: The first one will position individual glyph - images on the baseline, while the second one will render the glyphs. - As we will see, this has many advantages.</p> - - <p>We will thus start by storing individual glyph images, as well as - their position on the baseline. This can be done with code like:</p> - - <div class="pre"> - FT_GlyphSlot slot = face->glyph; <span class="comment">/* a small shortcut */</span> - FT_UInt glyph_index; - FT_Bool use_kerning; - FT_UInt previous; - int pen_x, pen_y, n; - - FT_Glyph glyphs[MAX_GLYPHS]; <span class="comment">/* glyph image */</span> - FT_Vector pos [MAX_GLYPHS]; <span class="comment">/* glyph position */</span> - FT_UInt num_glyphs; - - - ... initialize library ... - ... create face object ... - ... set character size ... - - pen_x = 0; <span class="comment">/* start at (0,0) */</span> - pen_y = 0; - - num_glyphs = 0; - use_kerning = FT_HAS_KERNING( face ); - previous = 0; - - for ( n = 0; n < num_chars; n++ ) + <span class="comment">/* check that we really grew the string bbox */</span> + if ( bbox.xMin > bbox.xMax ) { - <span class="comment">/* convert character code to glyph index */</span> - glyph_index = FT_Get_Char_Index( face, text[n] ); - - <span class="comment">/* retrieve kerning distance and move pen position */</span> - if ( use_kerning && previous && glyph_index ) - { - FT_Vector delta; - + bbox.xMin = 0; + bbox.yMin = 0; + bbox.xMax = 0; + bbox.yMax = 0; + } - FT_Get_Kerning( face, previous, glyph_index, - FT_KERNING_DEFAULT, &delta ); + <span class="comment">/* return string bbox */</span> + *abbox = bbox; +}</pre> + + <p>The resulting bounding box dimensions are expressed in + integer pixels and can then be used to compute the final + pen position before rendering the string.</p> + + <p class="warning">In general, the above function + does <em>not</em> compute an exact bounding box of a + string! As soon as hinting is involved, glyph + dimensions <em>must</em> be derived from the resulting + outlines. For anti-aliased pixmaps, + <tt>FT_Outline_Get_BBox</tt> then yields proper results. + In case you need 1-bit monochrome bitmaps, it is even + necessary to actually render the glyphs because the rules + for the conversion from outline to bitmap can also be + controlled by hinting instructions.</p> + + <pre> +<span class="comment">/* compute string dimensions in integer pixels */</span> +string_width = string_bbox.xMax - string_bbox.xMin; +string_height = string_bbox.yMax - string_bbox.yMin; + +<span class="comment">/* compute start pen position in 26.6 Cartesian pixels */</span> +start_x = ( ( my_target_width - string_width ) / 2 ) * 64; +start_y = ( ( my_target_height - string_height ) / 2 ) * 64; + +for ( n = 0; n < num_glyphs; n++ ) +{ + FT_Glyph image; + FT_Vector pen; - pen_x += delta.x >> 6; - } - <span class="comment">/* store current pen position */</span> - pos[num_glyphs].x = pen_x; - pos[num_glyphs].y = pen_y; + image = glyphs[n]; - <span class="comment">/* load glyph image into the slot without rendering */</span> - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); - if ( error ) - continue; <span class="comment">/* ignore errors, jump to next glyph */</span> + pen.x = start_x + pos[n].x; + pen.y = start_y + pos[n].y; - <span class="comment">/* extract glyph image and store it in our table */</span> - error = FT_Get_Glyph( face->glyph, &glyphs[num_glyphs] ); - if ( error ) - continue; <span class="comment">/* ignore errors, jump to next glyph */</span> + error = FT_Glyph_To_Bitmap( &image, FT_RENDER_MODE_NORMAL, + &pen, 0 ); + if ( !error ) + { + FT_BitmapGlyph bit = (FT_BitmapGlyph)image; - <span class="comment">/* increment pen position */</span> - pen_x += slot->advance.x >> 6; - <span class="comment">/* record current glyph index */</span> - previous = glyph_index; + my_draw_bitmap( bit->bitmap, + bit->left, + my_target_height - bit->top ); - <span class="comment">/* increment number of glyphs */</span> - num_glyphs++; + FT_Done_Glyph( image ); } - </div> - - <p>This is a very slight variation of our previous code where we - extract each glyph image from the slot, and store it, along with the - corresponding position, in our tables.</p> +}</pre> - <p>Note also that <tt>pen_x</tt> contains the total advance for the - string of text. We can now compute the bounding box of the text - string with a simple function like:</p> + <p>Some remarks.</p> - <div class="pre"> - void compute_string_bbox( FT_BBox *abbox ) - { - FT_BBox bbox; - FT_BBox glyph_bbox; + <ul> + <li>The pen position is expressed in the Cartesian space + (i.e., y upwards).</li> + <li>We call <tt>FT_Glyph_To_Bitmap</tt> with + the <tt>destroy</tt> parameter set to 0 (false), in + order to avoid destroying the original glyph image. The + new glyph bitmap is accessed through + <tt>image</tt> after the call and is typecast to + <tt>FT_BitmapGlyph</tt>.</li> - <span class="comment">/* initialize string bbox to "empty" values */</span> - bbox.xMin = bbox.yMin = 32000; - bbox.xMax = bbox.yMax = -32000; + <li>We use translation when + calling <tt>FT_Glyph_To_Bitmap</tt>. This ensures that + the <tt>left</tt> and <tt>top</tt> fields of the bitmap + glyph object are already set to the correct pixel + coordinates in the Cartesian space.</li> - <span class="comment">/* for each glyph image, compute its bounding box, */</span> - <span class="comment">/* translate it, and grow the string bbox */</span> - for ( n = 0; n < num_glyphs; n++ ) - { - FT_Glyph_Get_CBox( glyphs[n], ft_glyph_bbox_pixels, - &glyph_bbox ); + <li>Of course, we still need to convert pixel coordinates + from Cartesian to device space before rendering, hence + the <tt>my_target_height - bitmap->top</tt> in the call + to <tt>my_draw_bitmap</tt>.</li> + </ul> - glyph_bbox.xMin += pos[n].x; - glyph_bbox.xMax += pos[n].x; - glyph_bbox.yMin += pos[n].y; - glyph_bbox.yMax += pos[n].y; + <p>The same loop can be used to render the string anywhere + on our display surface, without the need to reload our + glyph images each time.</p> - if ( glyph_bbox.xMin < bbox.xMin ) - bbox.xMin = glyph_bbox.xMin; - if ( glyph_bbox.yMin < bbox.yMin ) - bbox.yMin = glyph_bbox.yMin; + <h3 id="section-5">5. Advanced Text Rendering: + Transformation and Centering and Kerning</h3> - if ( glyph_bbox.xMax > bbox.xMax ) - bbox.xMax = glyph_bbox.xMax; + <p>We are now going to modify our code in order to be able + to easily transform the rendered string, for example, to + rotate it. First, some minor improvements.</p> - if ( glyph_bbox.yMax > bbox.yMax ) - bbox.yMax = glyph_bbox.yMax; - } - - <span class="comment">/* check that we really grew the string bbox */</span> - if ( bbox.xMin > bbox.xMax ) - { - bbox.xMin = 0; - bbox.yMin = 0; - bbox.xMax = 0; - bbox.yMax = 0; - } - - <span class="comment">/* return string bbox */</span> - *abbox = bbox; - } - </div> + <h4>a. Packing and Translating Glyphs</h4> - <p>The resulting bounding box dimensions are expressed in integer - pixels and can then be used to compute the final pen position before - rendering the string as in:</p> + <p>We start by packing the information related to a single + glyph image into a single structure instead of parallel + arrays.</p> - <div class="pre"> - <span class="comment">/* compute string dimensions in integer pixels */</span> - string_width = string_bbox.xMax - string_bbox.xMin; - string_height = string_bbox.yMax - string_bbox.yMin; + <pre> +typedef struct TGlyph_ +{ + FT_UInt index; <span class="comment">/* glyph index */</span> + FT_Vector pos; <span class="comment">/* glyph origin on the baseline */</span> + FT_Glyph image; <span class="comment">/* glyph image */</span> - <span class="comment">/* compute start pen position in 26.6 cartesian pixels */</span> - start_x = ( ( my_target_width - string_width ) / 2 ) * 64; - start_y = ( ( my_target_height - string_height ) / 2 ) * 64; +} TGlyph, *PGlyph;</pre> - for ( n = 0; n < num_glyphs; n++ ) - { - FT_Glyph image; - FT_Vector pen; + <p>We also translate each glyph image directly after it is + loaded to its position on the baseline at load time. As + we will see, this has several advantages. Here is our new + glyph sequence loader.</p> + <pre> +FT_GlyphSlot slot = face->glyph; <span class="comment">/* a small shortcut */</span> +FT_UInt glyph_index; +FT_Bool use_kerning; +FT_UInt previous; +int pen_x, pen_y, n; - image = glyphs[n]; +TGlyph glyphs[MAX_GLYPHS]; <span class="comment">/* glyphs table */</span> +PGlyph glyph; <span class="comment">/* current glyph in table */</span> +FT_UInt num_glyphs; - pen.x = start_x + pos[n].x; - pen.y = start_y + pos[n].y; - error = FT_Glyph_To_Bitmap( &image, FT_RENDER_MODE_NORMAL, - &pen, 0 ); - if ( !error ) - { - FT_BitmapGlyph bit = (FT_BitmapGlyph)image; +... initialize library ... +... create face object ... +... set character size ... +pen_x = 0; <span class="comment">/* start at (0,0) */</span> +pen_y = 0; - my_draw_bitmap( bit->bitmap, - bit->left, - my_target_height - bit->top ); +num_glyphs = 0; +use_kerning = FT_HAS_KERNING( face ); +previous = 0; - FT_Done_Glyph( image ); - } - } - </div> +glyph = glyphs; +for ( n = 0; n < num_chars; n++ ) +{ + glyph->index = FT_Get_Char_Index( face, text[n] ); - <p>Some remarks:</p> - - <ul> - <li> - <p>The pen position is expressed in the cartesian space (i.e., - y upwards).</p> - </li> - - <li> - <p>We call <tt>FT_Glyph_To_Bitmap</tt> with the <tt>destroy</tt> - parameter set to 0 (false), in order to avoid destroying the - original glyph image. The new glyph bitmap is accessed through - <tt>image</tt> after the call and is typecast to - <tt>FT_BitmapGlyph</tt>.</p> - </li> - - <li> - <p>We use translation when calling <tt>FT_Glyph_To_Bitmap</tt>. - This ensures that the <tt>left</tt> and <tt>top</tt> fields of the - bitmap glyph object are already set to the correct pixel - coordinates in the cartesian space.</p> - </li> - - <li> - <p>Of course, we still need to convert pixel coordinates from - cartesian to device space before rendering, hence the - <tt>my_target_height - bitmap->top</tt> in the call to - <tt>my_draw_bitmap</tt>.</p> - </li> - </ul> - - <p>The same loop can be used to render the string anywhere on our - display surface, without the need to reload our glyph images each - time. We could also decide to implement word wrapping, and only - draw</p> - - <hr> - - <h3> - 5. Advanced text rendering: transformation + centering + kerning - </h3> - - <p>We are now going to modify our code in order to be able to easily - transform the rendered string, for example to rotate it. We will start - by performing a few minor improvements:</p> - - <h4> - a. packing & translating glyphs - </h4> - - <p>We start by packing the information related to a single glyph image - into a single structure instead of parallel arrays. We thus define - the following structure type:</p> - - <div class="pre"> - typedef struct TGlyph_ + if ( use_kerning && previous && glyph->index ) { - FT_UInt index; <span class="comment">/* glyph index */</span> - FT_Vector pos; <span class="comment">/* glyph origin on the baseline */</span> - FT_Glyph image; <span class="comment">/* glyph image */</span> + FT_Vector delta; - } TGlyph, *PGlyph; - </div> - <p>We also translate each glyph image directly after it is loaded to - its position on the baseline at load time. As we will see, this has - several advantages. Our glyph sequence loader thus becomes:</p> + FT_Get_Kerning( face, previous, glyph->index, + FT_KERNING_MODE_DEFAULT, &delta ); - <div class="pre"> - FT_GlyphSlot slot = face->glyph; <span class="comment">/* a small shortcut */</span> - FT_UInt glyph_index; - FT_Bool use_kerning; - FT_UInt previous; - int pen_x, pen_y, n; + pen_x += delta.x >> 6; + } - TGlyph glyphs[MAX_GLYPHS]; <span class="comment">/* glyphs table */</span> - PGlyph glyph; <span class="comment">/* current glyph in table */</span> - FT_UInt num_glyphs; + <span class="comment">/* store current pen position */</span> + glyph->pos.x = pen_x; + glyph->pos.y = pen_y; + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); + if ( error ) continue; - ... initialize library ... - ... create face object ... - ... set character size ... + error = FT_Get_Glyph( face->glyph, &glyph->image ); + if ( error ) continue; - pen_x = 0; <span class="comment">/* start at (0,0) */</span> - pen_y = 0; + <span class="comment">/* translate the glyph image now */</span> + FT_Glyph_Transform( glyph->image, 0, &glyph->pos ); - num_glyphs = 0; - use_kerning = FT_HAS_KERNING( face ); - previous = 0; + pen_x += slot->advance.x >> 6; + previous = glyph->index; - glyph = glyphs; - for ( n = 0; n < num_chars; n++ ) - { - glyph->index = FT_Get_Char_Index( face, text[n] ); + <span class="comment">/* increment number of glyphs */</span> + glyph++; +} - if ( use_kerning && previous && glyph->index ) - { - FT_Vector delta; +<span class="comment">/* count number of glyphs loaded */</span> +num_glyphs = glyph - glyphs;</pre> + <p>Note that translating glyphs now has several advantages. + The first one is that we don't need to translate the glyph + bbox when we compute the string's bounding box.</p> - FT_Get_Kerning( face, previous, glyph->index, - FT_KERNING_MODE_DEFAULT, &delta ); + <pre> +void compute_string_bbox( FT_BBox *abbox ) +{ + FT_BBox bbox; - pen_x += delta.x >> 6; - } - <span class="comment">/* store current pen position */</span> - glyph->pos.x = pen_x; - glyph->pos.y = pen_y; + bbox.xMin = bbox.yMin = 32000; + bbox.xMax = bbox.yMax = -32000; - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); - if ( error ) continue; + for ( n = 0; n < num_glyphs; n++ ) + { + FT_BBox glyph_bbox; - error = FT_Get_Glyph( face->glyph, &glyph->image ); - if ( error ) continue; - <span class="comment">/* translate the glyph image now */</span> - FT_Glyph_Transform( glyph->image, 0, &glyph->pos ); + FT_Glyph_Get_CBox( glyphs[n], ft_glyph_bbox_pixels, + &glyph_bbox ); - pen_x += slot->advance.x >> 6; - previous = glyph->index; + if (glyph_bbox.xMin < bbox.xMin) + bbox.xMin = glyph_bbox.xMin; - <span class="comment">/* increment number of glyphs */</span> - glyph++; - } + if (glyph_bbox.yMin < bbox.yMin) + bbox.yMin = glyph_bbox.yMin; - <span class="comment">/* count number of glyphs loaded */</span> - num_glyphs = glyph - glyphs; - </div> + if (glyph_bbox.xMax > bbox.xMax) + bbox.xMax = glyph_bbox.xMax; - <p>Note that translating glyphs now has several advantages. The first - one is that we don't need to translate the glyph bbox when we compute - the string's bounding box. The code becomes:</p> + if (glyph_bbox.yMax > bbox.yMax) + bbox.yMax = glyph_bbox.yMax; + } - <div class="pre"> - void compute_string_bbox( FT_BBox *abbox ) + if ( bbox.xMin > bbox.xMax ) { - FT_BBox bbox; + bbox.xMin = 0; + bbox.yMin = 0; + bbox.xMax = 0; + bbox.yMax = 0; + } + *abbox = bbox; +}</pre> - bbox.xMin = bbox.yMin = 32000; - bbox.xMax = bbox.yMax = -32000; + <p>With the above modifications, + the <tt>compute_string_bbox</tt> function can now compute + the bounding box of a transformed glyph string, which + allows further code simplications.</p> - for ( n = 0; n < num_glyphs; n++ ) - { - FT_BBox glyph_bbox; + <pre> +FT_BBox bbox; +FT_Matrix matrix; +FT_Vector delta; - FT_Glyph_Get_CBox( glyphs[n], ft_glyph_bbox_pixels, - &glyph_bbox ); +... load glyph sequence ... +... set up `matrix' and `delta' ... - if (glyph_bbox.xMin < bbox.xMin) - bbox.xMin = glyph_bbox.xMin; +<span class="comment">/* transform glyphs */</span> +for ( n = 0; n < num_glyphs; n++ ) + FT_Glyph_Transform( glyphs[n].image, &matrix, &delta ); - if (glyph_bbox.yMin < bbox.yMin) - bbox.yMin = glyph_bbox.yMin; +<span class="comment">/* compute bounding box of transformed glyphs */</span> +compute_string_bbox( &bbox );</pre> - if (glyph_bbox.xMax > bbox.xMax) - bbox.xMax = glyph_bbox.xMax; + <h4>b. Rendering a Transformed Glyph Sequence</h4> - if (glyph_bbox.yMax > bbox.yMax) - bbox.yMax = glyph_bbox.yMax; - } + <p>However, directly transforming the glyphs in our sequence + is not a good idea if we want to reuse them in order to + draw the text string with various angles or + transformations. It is better to perform the affine + transformation just before the glyph is rendered.</p> - if ( bbox.xMin > bbox.xMax ) - { - bbox.xMin = 0; - bbox.yMin = 0; - bbox.xMax = 0; - bbox.yMax = 0; - } + <pre> +FT_Vector start; +FT_Matrix matrix; - *abbox = bbox; - } - </div> +FT_Glyph image; +FT_Vector pen; +FT_BBox bbox; - <p>Now take a closer look: The <tt>compute_string_bbox</tt> function - can now compute the bounding box of a transformed glyph string. For - example, we can do something like:</p> - <div class="pre"> - FT_BBox bbox; - FT_Matrix matrix; - FT_Vector delta; +<span class="comment">/* get bbox of original glyph sequence */</span> +compute_string_bbox( &string_bbox ); +<span class="comment">/* compute string dimensions in integer pixels */</span> +string_width = (string_bbox.xMax - string_bbox.xMin) / 64; +string_height = (string_bbox.yMax - string_bbox.yMin) / 64; - ... load glyph sequence ... - ... set up "matrix" and "delta" ... +<span class="comment">/* set up start position in 26.6 Cartesian space */</span> +start.x = ( ( my_target_width - string_width ) / 2 ) * 64; +start.y = ( ( my_target_height - string_height ) / 2 ) * 64; - <span class="comment">/* transform glyphs */</span> - for ( n = 0; n < num_glyphs; n++ ) - FT_Glyph_Transform( glyphs[n].image, &matrix, &delta ); +<span class="comment">/* set up transform (a rotation here) */</span> +matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); +matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); +matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); +matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L ); - <span class="comment">/* compute bounding box of transformed glyphs */</span> - compute_string_bbox( &bbox ); - </div> +pen = start; - <h4> - b. Rendering a transformed glyph sequence - </h4> +for ( n = 0; n < num_glyphs; n++ ) +{ + <span class="comment">/* create a copy of the original glyph */</span> + error = FT_Glyph_Copy( glyphs[n].image, &image ); + if ( error ) continue; - <p>However, directly transforming the glyphs in our sequence is not a - good idea if we want to reuse them in order to draw the text string - with various angles or transformations. It is better to perform the - affine transformation just before the glyph is rendered, as in the - following code:</p> + <span class="comment">/* transform copy (this will also translate it to the */</span> + <span class="comment">/* correct position */</span> + FT_Glyph_Transform( image, &matrix, &pen ); - <div class="pre"> - FT_Vector start; - FT_Matrix matrix; + <span class="comment">/* check bounding box; if the transformed glyph image */</span> + <span class="comment">/* is not in our target surface, we can avoid rendering it */</span> + FT_Glyph_Get_CBox( image, ft_glyph_bbox_pixels, &bbox ); + if ( bbox.xMax <= 0 || bbox.xMin >= my_target_width || + bbox.yMax <= 0 || bbox.yMin >= my_target_height ) + continue; - FT_Glyph image; - FT_Vector pen; - FT_BBox bbox; - - - <span class="comment">/* get bbox of original glyph sequence */</span> - compute_string_bbox( &string_bbox ); - - <span class="comment">/* compute string dimensions in integer pixels */</span> - string_width = (string_bbox.xMax - string_bbox.xMin) / 64; - string_height = (string_bbox.yMax - string_bbox.yMin) / 64; + <span class="comment">/* convert glyph image to bitmap (destroy the glyph copy!) */</span> + error = FT_Glyph_To_Bitmap( + &image, + FT_RENDER_MODE_NORMAL, + 0, <span class="comment">/* no additional translation */</span> + 1 ); <span class="comment">/* destroy copy in "image" */</span> + if ( !error ) + { + FT_BitmapGlyph bit = (FT_BitmapGlyph)image; - <span class="comment">/* set up start position in 26.6 cartesian space */</span> - start.x = ( ( my_target_width - string_width ) / 2 ) * 64; - start.y = ( ( my_target_height - string_height ) / 2 ) * 64; - <span class="comment">/* set up transform (a rotation here) */</span> - matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); - matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); - matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); - matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L ); + my_draw_bitmap( bit->bitmap, + bit->left, + my_target_height - bit->top ); - pen = start; + <span class="comment">/* increment pen position -- */</span> + <span class="comment">/* we don't have access to a slot structure, */</span> + <span class="comment">/* so we have to use advances from glyph structure */</span> + <span class="comment">/* (which are in 16.16 fixed float format) */</span> + pen.x += image.advance.x >> 10; + pen.y += image.advance.y >> 10; - for ( n = 0; n < num_glyphs; n++ ) - { - <span class="comment">/* create a copy of the original glyph */</span> - error = FT_Glyph_Copy( glyphs[n].image, &image ); - if ( error ) continue; - - <span class="comment">/* transform copy (this will also translate it to the */</span> - <span class="comment">/* correct position */</span> - FT_Glyph_Transform( image, &matrix, &pen ); - - <span class="comment">/* check bounding box; if the transformed glyph image */</span> - <span class="comment">/* is not in our target surface, we can avoid rendering it */</span> - FT_Glyph_Get_CBox( image, ft_glyph_bbox_pixels, &bbox ); - if ( bbox.xMax <= 0 || bbox.xMin >= my_target_width || - bbox.yMax <= 0 || bbox.yMin >= my_target_height ) - continue; - - <span class="comment">/* convert glyph image to bitmap (destroy the glyph copy!) */</span> - error = FT_Glyph_To_Bitmap( - &image, - FT_RENDER_MODE_NORMAL, - 0, <span class="comment">/* no additional translation */</span> - 1 ); <span class="comment">/* destroy copy in "image" */</span> - if ( !error ) - { - FT_BitmapGlyph bit = (FT_BitmapGlyph)image; - - - my_draw_bitmap( bit->bitmap, - bit->left, - my_target_height - bit->top ); - - <span class="comment">/* increment pen position -- */</span> - <span class="comment">/* we don't have access to a slot structure, */</span> - <span class="comment">/* so we have to use advances from glyph structure */</span> - <span class="comment">/* (which are in 16.16 fixed float format) */</span> - pen.x += image.advance.x >> 10; - pen.y += image.advance.y >> 10; - - FT_Done_Glyph( image ); - } + FT_Done_Glyph( image ); } - </div> - - <p>There are a few changes compared to the original version of this - code:</p> - - <ul> - <li> - <p>We keep the original glyph images untouched; instead, we - transform a copy.</p> - </li> - - <li> - <p>We perform clipping computations in order to avoid rendering - & drawing glyphs that are not within our target surface</p> - </li> - - <li> - <p>We always destroy the copy when calling - <tt>FT_Glyph_To_Bitmap</tt> in order to get rid of the transformed - scalable image. Note that the image is not destroyed if the - function returns an error code (which is why - <tt>FT_Done_Glyph</tt> is only called within the compound - statement.</p> - </li> - - <li> - <p>The translation of the glyph sequence to the start pen position - is integrated in the call to <tt>FT_Glyph_Transform</tt> instead - of <tt>FT_Glyph_To_Bitmap</tt>.</p> - </li> - </ul> - - <p>It is possible to call this function several times to render the - string width different angles, or even change the way <tt>start</tt> - is computed in order to move it to different place.</p> - - <p>This code is the basis of the FreeType 2 demonstration program - named <tt>ftstring.c</tt>. It could be easily extended to perform - advanced text layout or word-wrapping in the first part, without - changing the second one.</p> - - <p>Note, however, that a normal implementation would use a glyph cache - in order to reduce memory needs. For example, let us assume that our - text string is ‘FreeType&rsquo'. We would store three identical - glyph images in our table for the letter ‘e’, which isn't - optimal (especially when you consider longer lines of text, or even - whole pages).</p> - - <hr> - - <h3> - 6. Accessing metrics in design font units, and scaling them - </h3> - - <p>Scalable font formats usually store a single vectorial image, called - an <em>outline</em>, for each glyph in a face. Each outline is defined - in an abstract grid called the <em>design space</em>, with coordinates - expressed in nominal <em>font units</em>. When a glyph image is loaded, - the font driver usually scales the outline to device space according to - the current character pixel size found in a <tt>FT_Size</tt> object. - The driver may also modify the scaled outline in order to significantly - improve its appearance on a pixel-based surface (a process known as - <em>hinting</em> or <em>grid-fitting</em>).</p> - - <p>This chapter describes how design coordinates are scaled to the - device space, and how to read glyph outlines and metrics in font units. - This is important for a number of things:</p> - - <ul> - <li> - <p>‘true’ WYSIWYG text layout</p> - </li> - <li> - <p>accessing font content for conversion or analysis purposes</p> - </li> - </ul> - - <h4> - a. Scaling distances to device space - </h4> - - <p>Design coordinates are scaled to the device space using a simple - scaling transformation whose coefficients are computed with the help - of the <em>character pixel size</em>:</p> - - <div class="example"> +}</pre> + + <p>There are a few changes compared to the original version + of this code.</p> + + <ul> + <li>We keep the original glyph images untouched; instead, + we transform a copy.</li> + + <li>We perform clipping computations in order to avoid + rendering and drawing glyphs that are not within our + target surface.</li> + + <li>We always destroy the copy when calling + <tt>FT_Glyph_To_Bitmap</tt> in order to get rid of the + transformed scalable image. Note that the image is not + destroyed if the function returns an error code (which + is why <tt>FT_Done_Glyph</tt> is only called within the + compound statement).</li> + + <li>The translation of the glyph sequence to the start pen + position is integrated into the call + to <tt>FT_Glyph_Transform</tt> instead + of <tt>FT_Glyph_To_Bitmap</tt>.</li> + </ul> + + <p>It is possible to call this function several times to + render the string with different angles, or even change + the way <tt>start</tt> is computed in order to move it to + different place.</p> + + <p>This code is the basis of the FreeType 2 + demonstration program + named <a href="http://git.savannah.gnu.org/cgit/freetype/freetype2-demos.git/tree/src/ftstring.c"><tt>ftstring.c</tt></a>. + It could be easily extended to perform advanced text + layout or word-wrapping in the first part, without + changing the second one.</p> + + <p>Note, however, that a normal implementation would use a + glyph cache in order to reduce memory needs. For example, + let us assume that our text string is + ‘FreeType’. We would store three identical + glyph images in our table for the letter ‘e’, + which isn't optimal (especially when you consider longer + lines of text, or even whole pages).</p> + + <p>A FreeType demo program that shows how glyph caching can + be implemented + is <a href="http://git.savannah.gnu.org/cgit/freetype/freetype2-demos.git/tree/src/ftview.c"><tt>ftview.c</tt></a>. + In general, ‘ftview’ is the main program used + by the FreeType developer team to check the validity of + loading, parsing, and rendering fonts.</p> + + + <h3 id="section-6">6. Accessing Metrics in Design Font + Units, and Scaling Them</h3> + + <p>Scalable font formats usually store a single vectorial + image, called an <em>outline</em>, for each glyph in a + face. Each outline is defined in an abstract grid called + the <em>design space</em>, with coordinates expressed in + <em>font units</em>. When a glyph image is loaded, the + font driver usually scales the outline to device space + according to the current character pixel size found in + an <a href="../reference/ft2-base_interface.html#FT_Size"><tt>FT_Size</tt></a> + object. The driver may also modify the scaled outline in + order to significantly improve its appearance on a + pixel-based surface (a process known as <em>hinting</em> + or <em>grid-fitting</em>).</p> + + <p>This section describes how design coordinates are scaled + to the device space, and how to read glyph outlines and + metrics in font units. This is important for a number of + things.</p> + + <ul> + <li>‘True’ WYSIWYG text layout.</li> + <li>Accessing font content for conversion or analysis + purposes.</li> + </ul> + + <h4>a. Scaling Distances to Device Space</h4> + + <p>Design coordinates are scaled to the device space using a + simple scaling transformation whose coefficients are + computed with the help of the <em>character pixel + size</em>.</p> + + <pre class="example"> device_x = design_x * x_scale device_y = design_y * y_scale x_scale = pixel_size_x / EM_size - y_scale = pixel_size_y / EM_size + y_scale = pixel_size_y / EM_size</pre> + + <p>Here, the value <tt>EM_size</tt> is font-specific and + corresponds to the size of an abstract square of the + design space (called the <em>EM</em>), which is used by + font designers to create glyph images. It is thus + expressed in font units. It is also accessible directly + for scalable font formats + as <tt>face->units_per_EM</tt>. You should check that + a font face contains scalable glyph images by using + the <tt>FT_IS_SCALABLE</tt> macro, which returns true if + appropriate.</p> + + <p>When you call the + function <a href="../reference/ft2-base_interface.html#FT_Set_Pixel_Sizes"><tt>FT_Set_Pixel_Sizes</tt></a>, + you are specifying the value of <tt>pixel_size_x</tt> and + <tt>pixel_size_y</tt> FreeType shall use. The library will + immediately compute the values of <tt>x_scale</tt> and + <tt>y_scale</tt>.</p> + + <p>When you call the + function <a href="../reference/ft2-base_interface.html#FT_Set_Char_Size"><tt>FT_Set_Char_Size</tt></a>, + you are specifying the character size in + physical <em>points</em>, which is used, along with the + device's resolutions, to compute the character pixel size + and the corresponding scaling factors.</p> + + <p>Note that after calling any of these two functions, you + can access the values of the character pixel size and + scaling factors as fields of + the <tt>face->size->metrics</tt> structure.</p> + + <dl> + <dt>x_ppem</dt> + <dd>The field name stands for ‘x pixels per + EM’; this is the horizontal size in integer pixels + of the EM square, which also is the <em>horizontal + character pixel size</em>, called <tt>pixel_size_x</tt> + in the above example.</dd> + + <dt>y_ppem</dt> + <dd>The field name stands for ‘y pixels per + EM’; this is the vertical size in integer pixels + of the EM square, which also is the <em>vertical + character pixel size</em>, called <tt>pixel_size_y</tt> + in the above example.</dd> + + <dt>x_scale</dt> + <dd>This is a 16.16 fixed-point scale to directly scale + horizontal distances from design space to 1/64th of + device pixels.</dd> + + <dt>y_scale</dt> + <dd>This is a 16.16 fixed-point scale to directly scale + vertical distances from design space to 1/64th of device + pixels.</dd> + </dl> + + <p>You can scale a distance expressed in font units to 26.6 + pixel format directly with the help of + the <a href="../reference/ft2-computations.html#FT_MulFix"><tt>FT_MulFix</tt></a> + function.</p> + + <pre> +<span class="comment">/* convert design distances to 1/64th of pixels */</span> +pixels_x = FT_MulFix( design_x, face->size->metrics.x_scale ); +pixels_y = FT_MulFix( design_y, face->size->metrics.y_scale );</pre> + + <p>Alternatively, you can also scale the value directly with + more accuracy by using doubles.</p> + + <pre> +FT_Size_Metrics* metrics = &face->size->metrics; <span class="comment">/* shortcut */</span> +double pixels_x, pixels_y; +double em_size, x_scale, y_scale; + + +<span class="comment">/* compute floating point scale factors */</span> +em_size = 1.0 * face->units_per_EM; +x_scale = metrics->x_ppem / em_size; +y_scale = metrics->y_ppem / em_size; + +<span class="comment">/* convert design distances to floating point pixels */</span> +pixels_x = design_x * x_scale; +pixels_y = design_y * y_scale;</pre> + + <h4>b. Accessing Design Metrics (Glyph & Global)</h4> + + <p>You can access glyph metrics in font units simply by + specifying the <tt>FT_LOAD_NO_SCALE</tt> bit flag + in <tt>FT_Load_Glyph</tt> or <tt>FT_Load_Char</tt>. The + metrics returned in <tt>face->glyph->metrics</tt> + will all be in font units.</p> + + <p>You can access unscaled kerning data using the + <tt>FT_KERNING_MODE_UNSCALED</tt> mode.</p> + + <p>Finally, a few global metrics are available directly in + font units as fields of the <tt>FT_Face</tt> handle, as + described in <a href="#section-3">section 3</a> of + this part.</p> + + + <h3 id="conclusion">Conclusion</h3> + + <p>This is the end of the second part of the FreeType + tutorial. You are now able to access glyph metrics, + manage glyph images, and render text much more + intelligently (kerning, measuring, transforming & + caching); this is sufficient knowledge to build a pretty + decent text service on top of FreeType.</p> + + <p>The demo programs in the ‘ft2demos’ bundle + (especially ‘ftview’) are a kind of reference + implementation, and are a good resource to turn to for + answers. They also show how to use additional features, + such as the glyph stroker and cache.</p> + </div> + + <!-- ************************************************** --> + + <div class="updated"> + <p>Last update: 12-Dec-2014</p> + </div> </div> + </div> - <p>Here, the value <tt>EM_size</tt> is font-specific and corresponds - to the size of an abstract square of the design space (called the - <em>EM</em>), which is used by font designers to create glyph images. - It is thus expressed in font units. It is also accessible directly - for scalable font formats as <tt>face->units_per_EM</tt>. You - should check that a font face contains scalable glyph images by using - the <tt>FT_IS_SCALABLE</tt> macro, which returns true when - appropriate.</p> - - <p>When you call the function <tt>FT_Set_Pixel_Sizes</tt>, you are - specifying the value of <tt>pixel_size_x</tt> and - <tt>pixel_size_y</tt> FreeType shall use. The library will - immediately compute the values of <tt>x_scale</tt> and - <tt>y_scale</tt>.</p> - - <p>When you call the function <tt>FT_Set_Char_Size</tt>, you are - specifying the character size in physical <em>points</em>, which is - used, along with the device's resolutions, to compute the character - pixel size and the corresponding scaling factors.</p> - - <p>Note that after calling any of these two functions, you can access - the values of the character pixel size and scaling factors as fields - of the <tt>face->size->metrics</tt> structure. These fields - are:</p> - - <center> - <table width="80%" cellpadding="5"> - <tr valign=top> - <td> - <tt>x_ppem</tt> - </td> - <td> - <p>The field name stands for ‘x pixels per EM’; - this is the horizontal size in integer pixels of the EM square, - which also is the <em>horizontal character pixel size</em>, called - <tt>pixel_size_x</tt> in the above example.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>y_ppem</tt> - </td> - <td> - <p>The field name stands for ‘y pixels per EM’; - this is the vertical size in integer pixels of the EM square, - which also is the <em>vertical character pixel size</em>, called - <tt>pixel_size_y</tt> in the above example.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>x_scale</tt> - </td> - <td> - <p>This is a 16.16 fixed-point scale that is used to directly - scale horizontal distances from design space to 1/64th of device - pixels.</p> - </td> - </tr> - <tr valign=top> - <td> - <tt>y_scale</tt> - </td> - <td> - <p>This is a 16.16 fixed-point scale that is used to directly - scale vertical distances from design space to 1/64th of device - pixels.</p> - </td> - </tr> - </table> - </center> - - <p>You can scale a distance expressed in font units to 26.6 pixel - format directly with the help of the <tt>FT_MulFix</tt> function, as - in:</p> - - <div class="pre"> - <span class="comment">/* convert design distances to 1/64th of pixels */</span> - pixels_x = FT_MulFix( design_x, face->size->metrics.x_scale ); - pixels_y = FT_MulFix( design_y, face->size->metrics.y_scale ); - </div> - - <p>However, you can also scale the value directly with more accuracy - by using doubles:</p> - - <div class="pre"> - FT_Size_Metrics* metrics = &face->size->metrics; <span class="comment">/* shortcut */</span> - double pixels_x, pixels_y; - double em_size, x_scale, y_scale; - - - <span class="comment">/* compute floating point scale factors */</span> - em_size = 1.0 * face->units_per_EM; - x_scale = metrics->x_ppem / em_size; - y_scale = metrics->y_ppem / em_size; - - <span class="comment">/* convert design distances to floating point pixels */</span> - pixels_x = design_x * x_scale; - pixels_y = design_y * y_scale; - </div> - - <h4> - b. Accessing design metrics (glyph & global) - </h4> - - <p>You can access glyph metrics in font units simply by specifying the - <tt>FT_LOAD_NO_SCALE</tt> bit flag in <tt>FT_Load_Glyph</tt> or - <tt>FT_Load_Char</tt>. The metrics returned in - <tt>face->glyph->metrics</tt> will all be in font units.</p> - - <p>You can access unscaled kerning data using the - <tt>FT_KERNING_MODE_UNSCALED</tt> mode.</p> - - <p>Finally, a few global metrics are available directly in font units - as fields of the <tt>FT_Face</tt> handle, as described in - chapter 3 of this section.</p> - - <hr> - - <h3> - Conclusion - </h3> - <p>This is the end of the second section of the FreeType 2 - tutorial. You are now able to access glyph metrics, manage glyph - images, and render text much more intelligently (kerning, measuring, - transforming & caching).</p> + <!-- ************************************************** --> - <p>You have now sufficient knowledge to build a pretty decent text - service on top of FreeType 2, and you could possibly stop here if - you want.</p> + <div class="col2"> + </div> + </div> +</div> - <p>The demo programs in the ‘ft2demos’ bundle (especially - ‘ftview’) are a kind of reference implementation, and are a - good resource to turn to for answers. They also show how to use - additional features, such as the glyph stroker and cache.</p> - <p>The next section will deal with FreeType 2 internals (like - modules, vector outlines, font drivers, renderers), as well as a few - font format specific issues (mainly, how to access certain TrueType or - Type 1 tables).</p> +<!-- ************************************************** --> -</td></tr> -</table> -</center> +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="index.html">FreeType Tutorial</a> + </li> + <li class="tertiary"> + <a href="step1.html">Simple Glyph Loading</a> + </li> + <li class="tertiary"> + <a href="step2.html" class="current">Managing Glyphs</a> + </li> + <li class="tertiary"> + <a href="step3.html">Examples</a> + </li> + </ul> +</div> -<h3 align=center> - <a href="step3.html">FreeType 2 Tutorial Step 3</a> -</h3> +</div> <!-- id="wrapper" --> -<p><font size=-3>Last update: 10-Apr-2013</font></p> +<div id="TOC-bottom"> +</div> </body> </html> diff --git a/lib/freetype/docs/tutorial/step3.html b/lib/freetype/docs/tutorial/step3.html index 4272f95d6..d3172e1b7 100644 --- a/lib/freetype/docs/tutorial/step3.html +++ b/lib/freetype/docs/tutorial/step3.html @@ -1,111 +1,171 @@ -<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" -"http://www.w3.org/TR/html4/loose.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> + <head> - <style type="text/css"> - body { font-family: Verdana, Geneva, Arial, Helvetica, serif; - color: #000000; - background: #FFFFFF; } - - p { text-align: justify; } - h1 { text-align: center; } - li { text-align: justify; } - td { padding: 0 0.5em 0 0.5em; } - - a:link { color: #0000EF; } - a:visited { color: #51188E; } - a:hover { color: #FF0000; } - - div.pre { font-family: monospace; - text-align: left; - white-space: pre; - color: blue; } - - div.example { font-family: monospace; - text-align: left; - white-space: pre; - color: purple; } - - span.comment { color: gray; } - </style> <meta http-equiv="Content-Type" - content="text/html; charset=iso-8859-1"> + content="text/html; charset=utf-8"> + <meta http-equiv="Content-Style-Type" + content="text/css"> + <meta http-equiv="Content-Script-Type" + content="text/javascript"> + <meta name="description" + content="FreeType Documentation"> <meta name="Author" content="David Turner"> - <title>FreeType 2 Tutorial</title> + + <link rel="icon" + href="../image/favicon_-90.ico"> + <link rel="shortcut icon" + href="../image/favicon_-90.ico"> + <link rel="stylesheet" + type="text/css" + href="../css/freetype2_-90.css"> + + <script type="text/javascript" + src="../javascript/jquery-1.11.0.min.js"> + </script> + <script type="text/javascript" + src="../javascript/jquery.ba-resize.min.js"> + </script> + <script type="text/javascript" + src="../javascript/freetype2.js"> + </script> + + <title>FreeType Tutorial / III</title> </head> -<body text="#000000" - bgcolor="#FFFFFF" - link="#0000EF" - vlink="#51188E" - alink="#FF0000"> -<h1 align=center> - FreeType 2 Tutorial<br> - Step 3 — handling internals -</h1> +<body> -<h3 align=center> - © 2010 Werner Lemberg - (<a href="mailto:wl@gnu.org">wl@gnu.org</a>)<br> - © 2010 The FreeType Development Team - (<a href="http://www.freetype.org">www.freetype.org</a>) -</h3> +<div id="top" + class="bar"> + <h1><a href="http://freetype.org/index.html">FreeType</a> + Tutorial / III</h1> +</div> -<center> -<table width="70%"> -<tr><td> - <hr> +<div id="wrapper"> - <h2> - Introduction - </h2> +<div class="colmask leftmenu"> + <div class="colright"> + <div class="col1wrap"> + <div class="col1"> - <p>This is the third section of the FreeType 2 tutorial. It - describes how to deal with various internals of the library like</p> - <ul> - <li>the module interface</li> - <li>functions for manipulating vector outlines</li> - <li>font driver issues</li> - <li>interaction with renderers using callbacks</li> - <li>accessing font specific data, for example PostScript font - dictionaries and TrueType tables</li> - </ul> + <!-- ************************************************** --> + + <div id="examples"> + <h2>III. Examples</h2> + + <p>For completeness, here again a link to + the <a href="example1.c">example</a> used and explained in + the <a href="step1.html">first part of the + tutorial</a>.</p> - <p>None of these items have been written yet.</p> + <p><a href="mailto:erik@timetrap.se">Erik Möller</a> + contributed a very nice C++ example that shows renderer + callbacks in action to draw a coloured glyph with a + differently coloured outline. The source code can be + found <a href="example2.cpp">here</a>.</p> - <h2> - Examples - </h2> + <p><a href="example3.cpp">Another example</a> demonstrates + how to use FreeType's stand-alone rasterizer, + <tt>ftraster.c</tt>, both in B/W and 5-levels gray mode. + You need files from FreeType version 2.3.10 or newer.</p> - <p><a href="mailto:erik@timetrap.se">Erik Möller</a> contributed a very - nice C++ example which shows renderer callbacks in action to draw a - coloured glyph with a differently coloured outline. The source code can - be found <a href="example2.cpp">here</a>.</p> + <p><a href="mailto:gsmiko@gmail.com">Róbert Márki</a> + contributed a small + <a href="example4.cpp">Qt demonstration program</a> + (together with its <a href="example4.pro">qmake file</a>) + that shows both direct rendering with a callback and + rendering with a buffer, yielding the same result. You + need FreeType 2.4.3 or newer.</p> + </div> - <p><a href="example3.cpp">Another example</a> demonstrates how to use - FreeType's stand-alone rasterizer, <tt>ftraster.c</tt>, both in B/W and - 5-levels gray mode. You need files from FreeType version 2.3.10 or - newer.</p> + <!-- ************************************************** --> - <p><a href="mailto:gsmiko@gmail.com">Róbert Márki</a> contributed a small - <a href="example4.cpp">Qt demonstration program</a> (together with its <a - href="example4.pro">qmake file</a>) which shows both direct rendering with - a callback and rendering with a buffer, yielding the same result. You - need FreeType 2.4.3 or newer.</p> + <div class="updated"> + <p>Last update: 13-Dec-2014</p> + </div> + </div> + </div> -</td></tr> -</table> -</center> -<h3 align=center> - <a href="step1.html">FreeType 2 Tutorial Step 1</a> -</h3> + <!-- ************************************************** --> + + <div class="col2"> + </div> + </div> +</div> + + +<!-- ************************************************** --> + +<div id="TOC"> + <ul> + <li class="funding"> + <p><a href="https://pledgie.com/campaigns/24434"> + <img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!" + src="https://pledgie.com/campaigns/24434.png?skin_name=chrome" + border="0" + align="middle"> + </a></p> + + <p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr" + target="_blank"> + <img class="with-border" + src="http://api.flattr.com/button/flattr-badge-large.png" + alt="Flattr this" + title="Flattr this" + border="0" + align="middle"> + </a></p> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html">Home</a> + </li> + <li class="primary"> + <a href="http://freetype.org/index.html#news">News</a> + </li> + <li class="primary"> + <a href="../index.html">Overview</a> + </li> + <li class="primary"> + <a href="../documentation.html">Documentation</a> + </li> + <li class="primary"> + <a href="http://freetype.org/developer.html">Development</a> + </li> + <li class="primary"> + <a href="http://freetype.org/contact.html" + class="emphasis">Contact</a> + </li> + + <li> + <!-- separate primary from secondary entries --> + </li> + + <li class="secondary"> + <a href="index.html">FreeType Tutorial</a> + </li> + <li class="tertiary"> + <a href="step1.html">Simple Glyph Loading</a> + </li> + <li class="tertiary"> + <a href="step2.html">Managing Glyphs</a> + </li> + <li class="tertiary"> + <a href="step3.html" class="current">Examples</a> + </li> + </ul> +</div> + +</div> <!-- id="wrapper" --> -<p><font size=-3>Last update: 07-Dec-2010</font></p> +<div id="TOC-bottom"> +</div> </body> </html> |