{"id":6291,"library":"uharfbuzz","title":"uharfbuzz: HarfBuzz Python Bindings","description":"uharfbuzz provides streamlined Cython bindings for the HarfBuzz shaping engine. It includes a minimal HarfBuzz source distribution by default, but can optionally link against a system-provided HarfBuzz. The library maintains an active development pace with frequent updates, often aligning with new HarfBuzz C library releases.","status":"active","version":"0.53.6","language":"en","source_language":"en","source_url":"https://github.com/harfbuzz/uharfbuzz","tags":["text-shaping","font-rendering","harfbuzz","cython","typography"],"install":[{"cmd":"pip install uharfbuzz","lang":"bash","label":"Default installation (bundles HarfBuzz)"},{"cmd":"USE_SYSTEM_LIBS=1 pip install uharfbuzz --no-binary :uharfbuzz:","lang":"bash","label":"Link against system HarfBuzz"}],"dependencies":[{"reason":"Core C library for text shaping. Bundled by default, or can be linked externally.","package":"harfbuzz","optional":true},{"reason":"Requires Python 3.10 or higher.","package":"python","version":">=3.10"}],"imports":[{"symbol":"harfbuzz","correct":"import uharfbuzz as hb"},{"note":"Used to load font data.","symbol":"Blob","correct":"hb.Blob"},{"note":"Represents a font face from a Blob.","symbol":"Face","correct":"hb.Face"},{"note":"Represents a font instance with a Face.","symbol":"Font","correct":"hb.Font"},{"note":"Used to hold text and shaping results.","symbol":"Buffer","correct":"hb.Buffer"},{"note":"The main text shaping function.","symbol":"shape","correct":"hb.shape(font, buf, features)"}],"quickstart":{"code":"import uharfbuzz as hb\nimport os\n\n# For demonstration, we'll assume a font file exists at this path.\n# In a real application, you'd load a font from a known path.\n# We'll use a placeholder and note to provide a real font path.\nFONT_PATH = os.environ.get('UHARFBUZZ_FONT_PATH', 'path/to/your/font.ttf')\nTEXT_TO_SHAPE = \"Hello, World!\"\n\nif not os.path.exists(FONT_PATH):\n    print(f\"Warning: Font file not found at {FONT_PATH}. Quickstart will use a dummy font file placeholder.\\n\" \\\n          \"Please replace 'path/to/your/font.ttf' with an actual font path or set UHARFBUZZ_FONT_PATH env var.\")\n    # Create a dummy file for the example to run without error, though it won't shape properly.\n    with open(FONT_PATH, 'wb') as f:\n        f.write(b'dummy font data')\n\n# 1. Load the font blob\nblob = hb.Blob.from_file_path(FONT_PATH)\n\n# 2. Create a font face and font instance\nface = hb.Face(blob)\nfont = hb.Font(face)\n\n# 3. Create a buffer and add text\nbuf = hb.Buffer()\nbuf.add_str(TEXT_TO_SHAPE)\nbuf.guess_segment_properties()\n\n# 4. Define shaping features (optional)\nfeatures = {\"kern\": True, \"liga\": True}\n\n# 5. Shape the text\nhb.shape(font, buf, features)\n\n# 6. Access shaped glyph information\ninfos = buf.glyph_infos\npositions = buf.glyph_positions\n\nprint(f\"Shaped '{TEXT_TO_SHAPE}' with {len(infos)} glyphs:\")\nfor info, pos in zip(infos, positions):\n    # gid = info.codepoint (this is actually glyph ID after shaping)\n    gid = info.codepoint\n    cluster = info.cluster\n    x_advance = pos.x_advance\n    x_offset = pos.x_offset\n    y_offset = pos.y_offset\n    glyph_name = font.glyph_to_string(gid)\n    print(f\"  {glyph_name} (gid={gid}, cluster={cluster}) @ advance={x_advance}, offset=({x_offset},{y_offset})\")\n\n# Clean up the dummy font file if it was created\nif os.environ.get('UHARFBUZZ_FONT_PATH') is None and os.path.exists(FONT_PATH) and b'dummy font data' in open(FONT_PATH, 'rb').read():\n    os.remove(FONT_PATH)\n","lang":"python","description":"This quickstart demonstrates how to load a font, create a buffer for text, apply OpenType shaping features, and retrieve the resulting glyph information and positions using uharfbuzz. A placeholder font path is used for demonstrative purposes; replace `path/to/your/font.ttf` with an actual font file or set the `UHARFBUZZ_FONT_PATH` environment variable for proper execution."},"warnings":[{"fix":"For a more user-friendly, higher-level interface, consider using `vharfbuzz`, which builds on top of `uharfbuzz` to simplify common text shaping tasks.","message":"uharfbuzz is a thin wrapper over the HarfBuzz C API. This means it exposes a low-level interface and requires manual handling of concepts like blobs, faces, fonts, and buffers, which can involve significant boilerplate compared to higher-level text rendering libraries.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure your system's HarfBuzz development package (e.g., `harfbuzz-devel` on Fedora) is up-to-date and was compiled with experimental API support. If building HarfBuzz from source, ensure the necessary flags are enabled.","message":"When linking against a system-provided HarfBuzz library using `USE_SYSTEM_LIBS=1`, the system HarfBuzz must be built with experimental API support enabled. If not, compilation or runtime errors related to missing APIs may occur.","severity":"breaking","affected_versions":"All versions using system libraries"},{"fix":"Refer to the `uharfbuzz` and HarfBuzz release notes for detailed changes between versions. Test your text shaping pipeline thoroughly after upgrading to catch any unexpected behavior or API nuances.","message":"Although the underlying HarfBuzz C library aims for API/ABI stability, frequent updates to HarfBuzz itself (which `uharfbuzz` tracks) can sometimes introduce new features or subtle behavioral changes in the low-level API that `uharfbuzz` exposes. While not always 'breaking' in a strict sense, new HarfBuzz versions might require adjustments to client code to leverage new capabilities or handle altered defaults.","severity":"gotcha","affected_versions":"All versions, especially when updating `uharfbuzz` across major HarfBuzz C library versions."}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z","problems":[]}