A simple shaping example

Below is the simplest HarfBuzz shaping example possible.

  1. Create a buffer and put your text in it.

      #include <hb.h>

      hb_buffer_t *buf;
      buf = hb_buffer_create();
      hb_buffer_add_utf8(buf, text, -1, 0, -1);
    
  1. Set the script, language and direction of the buffer.

      hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
      hb_buffer_set_script(buf, HB_SCRIPT_LATIN);
      hb_buffer_set_language(buf, hb_language_from_string("en", -1));
    
  1. Create a face and a font from a font file.

      hb_blob_t *blob = hb_blob_create_from_file(filename); /* or hb_blob_create_from_file_or_fail() */
      hb_face_t *face = hb_face_create(blob, 0);
      hb_font_t *font = hb_font_create(face);
    
  1. Shape!

      hb_shape(font, buf, NULL, 0);
    
  1. Get the glyph and position information.

      unsigned int glyph_count;
      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);
    
  1. Iterate over each glyph.

      hb_position_t cursor_x = 0;
      hb_position_t cursor_y = 0;
      for (unsigned int i = 0; i < glyph_count; i++) {
          hb_codepoint_t glyphid  = glyph_info[i].codepoint;
          hb_position_t x_offset  = glyph_pos[i].x_offset;
          hb_position_t y_offset  = glyph_pos[i].y_offset;
          hb_position_t x_advance = glyph_pos[i].x_advance;
          hb_position_t y_advance = glyph_pos[i].y_advance;
       /* draw_glyph(glyphid, cursor_x + x_offset, cursor_y + y_offset); */
          cursor_x += x_advance;
          cursor_y += y_advance;
      }
    
  1. Tidy up.

      hb_buffer_destroy(buf);
      hb_font_destroy(font);
      hb_face_destroy(face);
      hb_blob_destroy(blob);
    

This example shows enough to get us started using HarfBuzz. In the sections that follow, we will use the remainder of HarfBuzz's API to refine and extend the example and improve its text-shaping capabilities.