shithub: freetype+ttf2subf

ref: 47c14b9db3ebb058756971f0164a2fdc9125903a
dir: /docs/design/design-3.html/

View raw version
<html>
<head><title>The Design of FreeType 2 - Public Objects</title>
<basefont face="Georgia, Arial, Helvetica, Geneva">
<style content="text/css">
  P { text-align=justify }
  H1 { text-align=center }
  H2 { text-align=center }
  LI { text-align=justify }
</style>
</head>
<body text=#000000 bgcolor=#ffffff>

<center><table width="500"><tr><td>

<center><h1>The Design of FreeType 2</h1></center>

<table width="100%" cellpadding=5><tr bgcolor="#ccccee"><td>
<h1>II. Public Objects and Classes</h1>
</td></tr></table>

<p>We will now detail the abstractions provided by FreeType 2 to
   client applications to manage font files and data. As you would
   normally expect, these are implemented through objects/classes.</p>

<h2>1. Object Orientation in FreeType 2:</h2>

<p>Though written in ANSI C, the library employs a few
   techniques, inherited from object-oriented programming, to make
   it easy to extend. Hence, the following conventions apply in
   the FT2 source code:</p>

<ol>
  <li><p>
     each object type/class has a corresponding <em>structure type</em> <b>and</b>
     a corresponding <em>structure pointer type</em>. the latter is called the
     <em>handle type</em> for the type/class.</p>

  <p>Consider that we need to manage objects of type "foo" in FT2.
     We would define the following structure and handle types as
     follow:</p>

  <pre><font color="blue">
     typedef struct FT_FooRec_*    FT_Foo;

     typedef struct FT_FooRec_
     {
       // fields for the "foo" class
       ...

     } FT_FooRec;
  </font></pre>

  <p>As a convention, handle types use simple but meaningful identifiers
     beginning with "FT_", as in "FT_Foo", while structures use the same
     name with a "Rec" suffix appended to it ('Rec' is short for "record").
     <em>Note that each class type has a corresponding handle type</em>.
     </p>


  <li><p>
     class derivation is achieved internally by wrapping base class
     structures into new ones. As an example, let's define a "foobar"
     class that is derived from "foo". We would do something like:</p>

  <pre><font color="blue">
     typedef struct FT_FooBarRec_*    FT_FooBar;

     typedef struct FT_FooBarRec_
     {
       // the base "foo" class fields
       FT_FooRec     root;

       // fields proper to the "foobar" class
       ...

     } FT_FooBarRec;
  </font></pre>

  <p>As you can see, we ensure that a "foobar" object is also a "foo"
     object by placing a <tt>FT_FooRec</tt> at the start of the
     <tt>FT_FooBarRec</tt> definition. It is called <b>root</b>
     by convention.</p>

  <p>Note that a <tt>FT_FooBar</tt> handle also points to a "foo" object
     and can be typecasted to <tt>FT_Foo</tt>. Similarly, when the
     library handles a <tt>FT_Foo</tt> handle to client applications,
     the object can be really implemented as a <tt>FT_FooBar</tt> or any
     derived class from "foo".</p>

  </p></li>
</ul>

<p>Note that in the following sections of this chapter, we will refer
   to "the <tt>FT_Foo</tt> class" to indicate the type of objects
   handled through <tt>FT_Foo</tt> pointers, be they implemented as
   "foo" or "foobar".</p>

<hr>

<h2>2. The <em><b>FT_Library</b></em> class:</h2>

<p>This type corresponds to a handle to a single instance of the
   library. Note that the corresponding structure <tt>FT_LibraryRec</tt>
   is not defined in public header files, making client applications
   unable to access its internal fields.</p>

<p>The library object is the "parent" of all other objects in FreeType 2.
   You need to create a new library instance before doing anything else
   with the library. Similarly, destroying it will automatically
   destroy all its children (i.e. faces and modules).</p>

<p>Typical client applications should call <tt>FT_Init_FreeType</tt>,
   in order to create a new library object, ready to be used for
   further action.</p>

<p>Another alternative is to create a fresh new library instance
   by calling the function <tt>FT_New_Library</tt>, defined in the
   <tt>&lt;freetype/ftmodule.h&gt;</tt> public header file. This
   function will however return an "empty" library instance with
   no module registered in it. You can "install" modules in the
   instance by calling <tt>FT_Add_Module</tt> manually.</p>

<p>Calling <tt>FT_Init_FreeType</tt> is a lot more convenient, because
   this function basically registers a set of default modules into
   each new library instance. The way this list is accessed and/or
   computed is determined at build time, and depends on the content
   of the <b>ftinit</b> component. This process is explained in
   details later in this document.</p>

<p>For now, one should consider that library objects are created
   with <tt>FT_Init_FreeType</tt>, and destroyed along with all
   children with <tt>FT_Done_FreeType</tt>.</p>
<hr>

<h2>3. The <em><b>FT_Face</b></em> class:</h2>

<p>A face object corresponds to a single <em>font face</em>, i.e.
   a specific typeface with a specific style. For example, "Arial"
   and "Arial Italic" correspond to two distinct faces.</p>

<p>A face object is normally created through <tt>FT_New_Face</tt>.
   This function takes the following parameters: a <tt>FT_Library</tt>
   handle, a C file pathname used to indicate which font file to
   open, an index used to decide which face to load from the file
   (a single file may contain several faces in certain cases),
   as well as the address of a <tt>FT_Face</tt> handle. It returns
   an error code:</p>

<pre><font color="blue">
  FT_Error  FT_New_Face( FT_Library   library,
                         const char*  filepathname,
                         FT_Long      face_index,
                         FT_Face     *face );
</font></pre>

<p>in case of success, the function will return 0, and the handle
   pointed to by the "face" parameter will be set to a non-NULL value.</p>

<p>Note that the face object contains several fields used to
   describe global font data that can be accessed directly by
   client applications. For example, the total number of glyphs
   in the face, the face's family name, style name, the EM size
   for scalable formats, etc.. For more details, look at the
   <tt>FT_FaceRec</tt> definition in the FT2 API Reference.</p>

<hr>

<h2>4. The <em><b>FT_Size</b></em> class:</h2>

<p>Each <tt>FT_Face</tt> object <em>has</em> one or more <tt>FT_Size</tt>
   objects. A <em>size object</em> is used to store data specific to a
   given character width and height. Each newly created face object
   has one size, which is directly accessible as <tt>face-&gt;size</tt>.</p>

<p>The content of a size object can be changed by calling either
   <tt>FT_Set_Pixel_Sizes</tt> or <tt>FT_Set_Char_Size</tt>.</p>

<p>A new size object can be created with <tt>FT_New_Size</tt>, and
   destroyed manually with </tt>FT_Done_Size</tt>. Note that typical
   applications don't need to do this normally: they tend to use
   the default size object provided with each <tt>FT_Face</tt>.</p>

<p>The public fields of <tt>FT_Size</tt> objects are defined in
   a very small structure named <tt>FT_SizeRec</tt>. However, it is
   important to understand that some font drivers define their own
   derivatives of <tt>FT_Size</tt> to store important internal data
   that is re-computed each time the character size changes. Most of
   the time, these are size-specific <em>font hints</em>./p>

<p>For example, the TrueType driver stores the scaled CVT table that
   results from the execution of the "cvt" program in a <tt>TT_Size</tt>,
   while the Type 1 driver stores scaled global metrics (like blue zones)
   in a <tt>T1_Size</tt> object. Don't worry if you don't understand
   the current paragraph, most of this stuff is highly font format
   specific and doesn't need to be explained to client developers :-)</p>

<hr>

<h2>5. The <em><b>FT_GlyphSlot</b></em> class:</h2>

<p>The purpose of a glyph slot is to provide a place where glyph
   images can be loaded one by one easily, independently of the
   glyph image format (bitmap, vector outline, or anything else).</p>

<p>Ideally, once a glyph slot is created, any glyph image can
   be loaded into it without additional memory allocation. In practice,
   this is only possible with certain formats like TrueType which
   explicitely provide data to compute a slot's maximum size.</p>

<p>Another reason for glyph slots is that they're also used to hold
   format-specific hints for a given glyphs has well as all other
   data necessary to correctly load the glyph.</p>

<p>The base <tt>FT_GlyphSlotRec</tt> structure only presents glyph
   metrics and images to client applications, while actual implementation
   may contain more sophisticated data.</p>

<p>As an example, the TrueType-specific <tt>TT_GlyphSlotRec</tt>
   structure contains additional fields to hold glyph-specific bytecode,
   transient outlines used during the hinting process, and a few other
   things.

   the Type1-specific <tt>T1_GlyphSlotRec</tt> structure holds
   glyph hints during glyph loading, as well as additional logic used
   to properly hint the glyphs when a native T1 hinter is used.</p>

<p>Finally, each face object has a single glyph slot, that is directly
   accessible as <tt>face-&gt;glyph</tt>.</p>

<hr>

<h2>6. The <em><b>FT_CharMap</b></em> class:</h2>

<p>Finally, the <tt>FT_CharMap</tt> type is used as a handle to
   character map objects, or "charmaps" to be brief. A charmap is
   simply some sort of table or dictionary which is used to translate
   character codes in a given encoding into glyph indices for the
   font.</p>

<p>A single face may contain several charmaps. Each one of them
   corresponds to a given character repertoire, like Unicode, Apple Roman,
   Windows codepages, and other ugly "standards".</p>

<p>Each <tt>FT_CharMap</tt> object contains a "platform" and an "encoding"
   field used to identify precisely the character repertoire corresponding
   to it.</p>

<p>Each font format provides its own derivative of <tt>FT_CharMapRec</tt>
   and thus needs to implement these objects.</p>

<hr>
<h2>7. Objects relationships:</h2>

<p>The following diagram summarizes what we just said regarding the
   public objects managed by the library, as well as explicitely
   describes their relationships:</p>

<p>Note that this picture will be updated at the end of the next
   chapter, related to <em>internal objects</em>.</p>

</td></tr></table></center>
</body>
</html>