Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c6c6a17
docs: add binding generation documentation and migration plan
mattleibow Feb 1, 2026
f66a53b
feat(harfbuzz): update bindings to 2.9.1
mattleibow Feb 1, 2026
befdb35
feat(harfbuzz): update bindings to 3.4.0
mattleibow Feb 1, 2026
9dc5b76
feat(harfbuzz): update bindings to 4.4.1
mattleibow Feb 1, 2026
6418f49
feat(harfbuzz): update bindings to 5.3.1
mattleibow Feb 1, 2026
8965169
feat(harfbuzz): update bindings to 7.3.0
mattleibow Feb 1, 2026
0bdf732
feat(harfbuzz): update bindings to 8.3.0
mattleibow Feb 1, 2026
83eb73c
feat(harfbuzz): add C# wrappers and tests for new APIs
mattleibow Feb 1, 2026
4a7c749
docs: mark HarfBuzz migration plan complete
mattleibow Feb 1, 2026
996f918
feat(harfbuzz): add variable font and additional APIs
mattleibow Feb 2, 2026
22f0bc2
docs: document 8.3.1 parsing issue and attempted solutions
mattleibow Feb 2, 2026
32e4faf
refactor(harfbuzz): split HBNewApiTest.cs into appropriate test files
mattleibow Feb 2, 2026
00ab5c5
feat(harfbuzz): add Face.GetName and Face.TryGetName for OpenType names
mattleibow Feb 2, 2026
357ff1b
docs: update migration plan with recent API additions
mattleibow Feb 2, 2026
e0581af
feat(harfbuzz): add Font Ppem/Ptem and Face OpenType layout APIs
mattleibow Feb 2, 2026
3a41950
docs: update migration plan with latest APIs and test count
mattleibow Feb 2, 2026
91b18b4
feat(generator): upgrade CppAst to 0.24.0 with compatibility fixes
mattleibow Feb 2, 2026
1edea07
docs: update generator documentation for CppAst 0.24.0
mattleibow Feb 2, 2026
76fe46e
final generation
mattleibow Feb 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions binding/HarfBuzzSharp/Buffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ public Buffer ()
{
}

/// <summary>
/// Creates a new buffer with the same Unicode functions, content type, flags,
/// cluster level, direction, language, and script as the source buffer.
/// </summary>
/// <param name="source">The source buffer to copy settings from</param>
/// <returns>A new buffer with the same settings</returns>
public static Buffer CreateSimilar (Buffer source)
{
if (source == null)
throw new ArgumentNullException (nameof (source));
return new Buffer (HarfBuzzApi.hb_buffer_create_similar (source.Handle));
}

public ContentType ContentType {
get => HarfBuzzApi.hb_buffer_get_content_type (Handle);
set => HarfBuzzApi.hb_buffer_set_content_type (Handle, value);
Expand Down
47 changes: 47 additions & 0 deletions binding/HarfBuzzSharp/Definitions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,53 @@ public GlyphFlags GlyphFlags {
}
}

/// <summary>
/// OpenType layout table tags.
/// </summary>
public enum OpenTypeLayoutTableTag : uint
{
/// <summary>
/// The Glyph Substitution (GSUB) table.
/// </summary>
Gsub = ('G' << 24) | ('S' << 16) | ('U' << 8) | 'B',

/// <summary>
/// The Glyph Positioning (GPOS) table.
/// </summary>
Gpos = ('G' << 24) | ('P' << 16) | ('O' << 8) | 'S',
}

/// <summary>
/// Information about an OpenType layout feature's names.
/// </summary>
public struct OpenTypeFeatureNameIds
{
/// <summary>
/// The name ID for the feature's label (user-visible name).
/// </summary>
public OpenTypeNameId LabelId { get; set; }

/// <summary>
/// The name ID for the feature's tooltip.
/// </summary>
public OpenTypeNameId TooltipId { get; set; }

/// <summary>
/// The name ID for sample text demonstrating the feature.
/// </summary>
public OpenTypeNameId SampleId { get; set; }

/// <summary>
/// The number of named parameters for this feature.
/// </summary>
public int NumNamedParameters { get; set; }

/// <summary>
/// The name ID of the first named parameter.
/// </summary>
public OpenTypeNameId FirstParamId { get; set; }
}

public enum OpenTypeNameId
{
Copyright = 0,
Expand Down
171 changes: 171 additions & 0 deletions binding/HarfBuzzSharp/Face.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,177 @@ public Blob ReferenceTable (Tag table) =>

public void MakeImmutable () => HarfBuzzApi.hb_face_make_immutable (Handle);

/// <summary>
/// Gets the name string from the face's OpenType 'name' table.
/// </summary>
/// <param name="nameId">The name ID to retrieve.</param>
/// <returns>The name string, or an empty string if not found.</returns>
public string GetName (OpenTypeNameId nameId) =>
GetName (nameId, Language.Default);

/// <summary>
/// Gets the name string from the face's OpenType 'name' table.
/// </summary>
/// <param name="nameId">The name ID to retrieve.</param>
/// <param name="language">The language for the name.</param>
/// <returns>The name string, or an empty string if not found.</returns>
public string GetName (OpenTypeNameId nameId, Language language)
{
if (language == null)
throw new ArgumentNullException (nameof (language));

// First call to get the length
uint length = 0;
HarfBuzzApi.hb_ot_name_get_utf16 (Handle, nameId, language.Handle, &length, null);

if (length == 0)
return string.Empty;

// Allocate buffer and get the string
length++; // Add space for null terminator
var buffer = stackalloc ushort[(int)length];
HarfBuzzApi.hb_ot_name_get_utf16 (Handle, nameId, language.Handle, &length, buffer);

return new string ((char*)buffer, 0, (int)length);
}

/// <summary>
/// Tries to get the name string from the face's OpenType 'name' table.
/// </summary>
/// <param name="nameId">The name ID to retrieve.</param>
/// <param name="name">The name string, or null if not found.</param>
/// <returns>True if the name was found, false otherwise.</returns>
public bool TryGetName (OpenTypeNameId nameId, out string name) =>
TryGetName (nameId, Language.Default, out name);

/// <summary>
/// Tries to get the name string from the face's OpenType 'name' table.
/// </summary>
/// <param name="nameId">The name ID to retrieve.</param>
/// <param name="language">The language for the name.</param>
/// <param name="name">The name string, or null if not found.</param>
/// <returns>True if the name was found, false otherwise.</returns>
public bool TryGetName (OpenTypeNameId nameId, Language language, out string name)
{
if (language == null)
throw new ArgumentNullException (nameof (language));

// First call to get the length
uint length = 0;
HarfBuzzApi.hb_ot_name_get_utf16 (Handle, nameId, language.Handle, &length, null);

if (length == 0) {
name = null;
return false;
}

// Allocate buffer and get the string
length++; // Add space for null terminator
var buffer = stackalloc ushort[(int)length];
HarfBuzzApi.hb_ot_name_get_utf16 (Handle, nameId, language.Handle, &length, buffer);

name = new string ((char*)buffer, 0, (int)length);
return true;
}

/// <summary>
/// Gets all name entries from the face's OpenType 'name' table.
/// </summary>
/// <returns>An array of name entries.</returns>
public OpenTypeNameEntry[] GetAllNameEntries ()
{
uint count = 0;
var entries = HarfBuzzApi.hb_ot_name_list_names (Handle, &count);

if (count == 0 || entries == null)
return Array.Empty<OpenTypeNameEntry> ();

var result = new OpenTypeNameEntry[count];
for (int i = 0; i < count; i++)
result[i] = entries[i];

return result;
}

/// <summary>
/// Gets all script tags supported by the specified OpenType layout table.
/// </summary>
/// <param name="tableTag">The layout table to query (GSUB or GPOS).</param>
/// <returns>An array of script tags.</returns>
public Tag[] GetOpenTypeLayoutScriptTags (OpenTypeLayoutTableTag tableTag)
{
// First call to get the count
uint count = 0;
var total = HarfBuzzApi.hb_ot_layout_table_get_script_tags (Handle, (uint)tableTag, 0, &count, null);

if (total == 0)
return Array.Empty<Tag> ();

// Allocate and get all tags
var buffer = new Tag[total];
count = total;
fixed (Tag* ptr = buffer) {
HarfBuzzApi.hb_ot_layout_table_get_script_tags (Handle, (uint)tableTag, 0, &count, (uint*)ptr);
}

return buffer;
}

/// <summary>
/// Gets all feature tags supported by the specified OpenType layout table.
/// </summary>
/// <param name="tableTag">The layout table to query (GSUB or GPOS).</param>
/// <returns>An array of feature tags.</returns>
public Tag[] GetOpenTypeLayoutFeatureTags (OpenTypeLayoutTableTag tableTag)
{
// First call to get the count
uint count = 0;
var total = HarfBuzzApi.hb_ot_layout_table_get_feature_tags (Handle, (uint)tableTag, 0, &count, null);

if (total == 0)
return Array.Empty<Tag> ();

// Allocate and get all tags
var buffer = new Tag[total];
count = total;
fixed (Tag* ptr = buffer) {
HarfBuzzApi.hb_ot_layout_table_get_feature_tags (Handle, (uint)tableTag, 0, &count, (uint*)ptr);
}

return buffer;
}

/// <summary>
/// Tries to get the name IDs for an OpenType layout feature.
/// </summary>
/// <param name="tableTag">The layout table (GSUB or GPOS).</param>
/// <param name="featureIndex">The index of the feature in the table.</param>
/// <param name="nameIds">The name IDs for the feature if found.</param>
/// <returns>True if the feature has name IDs, false otherwise.</returns>
public bool TryGetOpenTypeLayoutFeatureNameIds (OpenTypeLayoutTableTag tableTag, int featureIndex, out OpenTypeFeatureNameIds nameIds)
{
OpenTypeNameId labelId, tooltipId, sampleId, firstParamId;
uint numParams;

var result = HarfBuzzApi.hb_ot_layout_feature_get_name_ids (
Handle, (uint)tableTag, (uint)featureIndex,
&labelId, &tooltipId, &sampleId, &numParams, &firstParamId);

if (!result) {
nameIds = default;
return false;
}

nameIds = new OpenTypeFeatureNameIds {
LabelId = labelId,
TooltipId = tooltipId,
SampleId = sampleId,
NumNamedParameters = (int)numParams,
FirstParamId = firstParamId
};
return true;
}

protected override void Dispose (bool disposing) =>
base.Dispose (disposing);

Expand Down
Loading
Loading