|  |  |  |  | 
    Once you have your face and font objects configured as desired and
    your input buffer is filled with the characters you need to shape,
    all you need to do is call hb_shape().
  
HarfBuzz will return the shaped version of the text in the same buffer that you provided, but it will be in output mode. At that point, you can iterate through the glyphs in the buffer, drawing each one at the specified position or handing them off to the appropriate graphics library.
For the most part, HarfBuzz's shaping step is straightforward from the outside. But that doesn't mean there will never be cases where you want to look under the hood and see what is happening on the inside. HarfBuzz provides facilities for doing that, too.
      The hb_shape() function call takes four arguments: the font
      object to use, the buffer of characters to shape, an array of
      user-specified features to apply, and the length of that feature
      array. The feature array can be NULL, so for the sake of
      simplicity we will start with that case.
    
      Internally, HarfBuzz looks  at the tables of the font file to
      determine where glyph classes, substitutions, and positioning
      are defined, using that information to decide which
      shaper to use (ot for
      OpenType fonts, aat for Apple Advanced
      Typography fonts, and so on). It also looks at the direction,
      script, and language properties of the segment to figure out
      which script-specific shaping model is needed (at least, in
      shapers that support multiple options).      
    
      If a font has a GDEF table, then that is used for
      glyph classes; if not, HarfBuzz will fall back to Unicode
      categorization by code point. If a font has an AAT morx table,
      then it is used for substitutions; if not, but there is a GSUB
      table, then the GSUB table is used. If the font has an AAT
      kerx table, then it is used for positioning; if not, but
      there is a GPOS table, then the GPOS table is used. If neither
      table is found, but there is a kern table, then HarfBuzz will
      use the kern table. If there is no kerx, no GPOS, and no
      kern, HarfBuzz will fall back to positioning marks itself.
    
With a well-behaved OpenType font, you expect GDEF, GSUB, and GPOS tables to all be applied. HarfBuzz implements the script-specific shaping models in internal functions, rather than in the public API.
The algorithms used for shaping can be quite involved; HarfBuzz tries to be compatible with the OpenType Layout specification and, wherever there is any ambiguity, HarfBuzz attempts to replicate the output of Microsoft's Uniscribe engine, to the extent that is feasible and desirable. See the Microsoft Typography pages for more detail.
      In general, though, all that you need to know is that
      hb_shape() returns the results of shaping
      in the same buffer that you provided. The buffer's content type
      will now be set to
      HB_BUFFER_CONTENT_TYPE_GLYPHS, indicating
      that it contains shaped output, rather than input text. You can
      now extract the glyph information and positioning arrays:
    
      hb_glyph_info_t *glyph_info    = hb_buffer_get_glyph_infos(buf, &glyph_count);
      hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count);
    
      The glyph information array holds a hb_glyph_info_t
      for each output glyph, which has two fields:
      codepoint and
      cluster. Whereas, in the input buffer,
      the codepoint field contained the Unicode
      code point, it now contains the glyph ID of the corresponding
      glyph in the font. The cluster field is
      an integer that you can use to help identify when shaping has
      reordered, split, or combined code points; we will say more
      about that in the next chapter.
    
      The glyph positions array holds a corresponding
      hb_glyph_position_t for each output glyph,
      containing four fields: x_advance,
      y_advance,
      x_offset, and
      y_offset. The advances tell you how far
      you need to move the drawing point after drawing this glyph,
      depending on whether you are setting horizontal text (in which
      case you will have x advances) or vertical text (for which you
      will have y advances). The x and y offsets tell you where to
      move to start drawing the glyph; usually you will have both and
      x and a y offset, regardless of the text direction.
    
Most of the time, you will rely on a font-rendering library or other graphics library to do the actual drawing of glyphs, so you will need to iterate through the glyphs in the buffer and pass the corresponding values off.