Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
52a68c3
Add baseline docs checklist
mattleibow Sep 1, 2025
7a06ffe
Add guide
mattleibow Sep 1, 2025
2dbb51a
Switch to the new way of doing docs
mattleibow Sep 4, 2025
462333a
HarfBuzzSharp
mattleibow Sep 5, 2025
961e0fd
SkiaSharp
mattleibow Sep 5, 2025
6ae56c7
Blazor
mattleibow Sep 5, 2025
40a3294
with BOM
mattleibow Sep 5, 2025
f5d4c25
regen
mattleibow Sep 5, 2025
190acca
Blazor
mattleibow Sep 5, 2025
eb4ae35
SkiaSharp.HarfBuzz
mattleibow Sep 5, 2025
6d2386d
fix
mattleibow Sep 5, 2025
08fc14f
android
mattleibow Sep 5, 2025
0d12f09
ios
mattleibow Sep 5, 2025
19b979a
macos
mattleibow Sep 5, 2025
2ee552b
apple
mattleibow Sep 5, 2025
646e0b8
Lots more now
mattleibow Sep 5, 2025
446af2f
methods
mattleibow Sep 5, 2025
8004c41
tizen
mattleibow Sep 5, 2025
841ecd5
Removed submodule docs
mattleibow Sep 5, 2025
c2d20a3
Delete API.Docs.Migration.Checklist.md
mattleibow Sep 5, 2025
be862bb
Delete API.Docs.Migration.Guide.md
mattleibow Sep 5, 2025
d3bc42f
back again
mattleibow Sep 5, 2025
028e273
add images from docs for now
mattleibow Sep 5, 2025
4f10d32
some fixes
mattleibow Sep 5, 2025
8c0231b
SkiaSharp is green
mattleibow Sep 5, 2025
6218a74
views are better
mattleibow Sep 5, 2025
301b14e
things look really green now
mattleibow Sep 5, 2025
88bb392
regen
mattleibow Sep 5, 2025
6f49926
Fix more things
mattleibow Sep 5, 2025
19833cb
more!
mattleibow Sep 5, 2025
f0460aa
Great!
mattleibow Sep 5, 2025
fddb822
Things should be good now...
mattleibow Sep 5, 2025
c9806a6
Merge branch 'main' into dev/inline-docs
mattleibow Sep 8, 2025
ac69d93
Merge branch 'main' into dev/inline-docs
mattleibow Sep 10, 2025
bc338a3
Merge remote-tracking branch 'origin/main' into dev/inline-docs
mattleibow Sep 10, 2025
9435f6d
oops
mattleibow Sep 10, 2025
7fe4b6f
Merge remote-tracking branch 'origin/main' into dev/inline-docs
mattleibow Sep 10, 2025
0e7e10e
add the xml too
mattleibow Sep 10, 2025
f6d32bb
Only copy the ref if it exists
mattleibow Sep 11, 2025
503a314
Merge branch 'main' into dev/inline-docs
mattleibow Oct 10, 2025
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
4 changes: 0 additions & 4 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,3 @@
path = externals/depot_tools
url = https://chromium.googlesource.com/chromium/tools/depot_tools.git
branch = master
[submodule "docs"]
path = docs
url = https://github.com/mono/SkiaSharp-API-docs
branch = master
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
<RootNamespace>SkiaSharp.Benchmarks</RootNamespace>
<AssemblyName>SkiaSharp.Benchmarks</AssemblyName>
<SkipGenerateAssemblyVersionInfo>true</SkipGenerateAssemblyVersionInfo>
<SkipMDocGenerateDocs>true</SkipMDocGenerateDocs>
<DebugType>pdbonly</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
Expand Down
61 changes: 61 additions & 0 deletions binding/HarfBuzzSharp/Blob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,47 @@

namespace HarfBuzzSharp
{
/// <summary>
/// Represents a blob of data in memory.
/// </summary>
public unsafe class Blob : NativeObject
{
private static readonly Lazy<Blob> emptyBlob = new Lazy<Blob> (() => new StaticBlob (HarfBuzzApi.hb_blob_get_empty ()));

/// <summary>
/// Gets a reference to the empty <see cref="Blob" /> instance.
/// </summary>
public static Blob Empty => emptyBlob.Value;

internal Blob (IntPtr handle)
: base (handle)
{
}

/// <summary>
/// Creates a new <see cref="Blob" /> instance, wrapping the specified data.
/// </summary>
/// <param name="data">The data to wrap.</param>
/// <param name="length">The length of the data being wrapped.</param>
/// <param name="mode">The memory mode to use.</param>
/// <remarks>
/// If there was a problem creating the blob, or if the data length was zero, then an empty blob will be created.
/// </remarks>
public Blob (IntPtr data, int length, MemoryMode mode)
: this (data, length, mode, null)
{
}

/// <summary>
/// Creates a new <see cref="Blob" /> instance, wrapping the specified data.
/// </summary>
/// <param name="data">The data to wrap.</param>
/// <param name="length">The length of the data being wrapped.</param>
/// <param name="mode">The memory mode to use.</param>
/// <param name="releaseDelegate">The delegate to invoke when the data is not needed anymore.</param>
/// <remarks>
/// If there was a problem creating the blob, or if the data length was zero, then an empty blob will be created.
/// </remarks>
public Blob (IntPtr data, int length, MemoryMode mode, ReleaseDelegate releaseDelegate)
: this (Create (data, length, mode, releaseDelegate))
{
Expand All @@ -36,28 +61,59 @@ protected override void DisposeHandler ()
}
}

/// <summary>
/// Gets the length of blob data in bytes.
/// </summary>
public int Length => (int)HarfBuzzApi.hb_blob_get_length (Handle);

/// <summary>
/// Gets the number of faces in this blob.
/// </summary>
public int FaceCount => (int)HarfBuzzApi.hb_face_count (Handle);

/// <summary>
/// Gets the value indicating whether the blob is immutable.
/// </summary>
public bool IsImmutable => HarfBuzzApi.hb_blob_is_immutable (Handle);

/// <summary>
/// Makes the blob immutable.
/// </summary>
public void MakeImmutable () => HarfBuzzApi.hb_blob_make_immutable (Handle);

/// <summary>
/// Returns a stream that wraps the data.
/// </summary>
/// <returns>Returns the stream that wraps the data.</returns>
/// <remarks>
/// If the data is released, then the stream becomes invalid.
/// </remarks>
public unsafe Stream AsStream ()
{
uint length;
var dataPtr = HarfBuzzApi.hb_blob_get_data (Handle, &length);
return new UnmanagedMemoryStream ((byte*)dataPtr, length);
}

/// <summary>
/// Returns a span that wraps the data.
/// </summary>
/// <returns>Returns the span that wraps the data.</returns>
/// <remarks>
/// If the data is released, then the span becomes invalid.
/// </remarks>
public unsafe Span<byte> AsSpan ()
{
uint length;
var dataPtr = HarfBuzzApi.hb_blob_get_data (Handle, &length);
return new Span<byte> (dataPtr, (int)length);
}

/// <summary>
/// Creates a new <see cref="Blob" /> instance from the contents of the file.
/// </summary>
/// <param name="fileName">The path to the file to load.</param>
/// <returns>Returns the new <see cref="Blob" /> instance.</returns>
public static Blob FromFile (string fileName)
{
if (!File.Exists (fileName)) {
Expand All @@ -68,6 +124,11 @@ public static Blob FromFile (string fileName)
return new Blob (blob);
}

/// <summary>
/// Creates a new <see cref="Blob" /> instance from the contents of the stream.
/// </summary>
/// <param name="stream">The stream to use.</param>
/// <returns>Returns the new <see cref="Blob" /> instance.</returns>
public static unsafe Blob FromStream (Stream stream)
{
// TODO: check to see if we can avoid the second copy (the ToArray)
Expand Down
62 changes: 62 additions & 0 deletions binding/HarfBuzzSharp/Buffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

namespace HarfBuzzSharp
{
/// <summary>
/// Represents a text buffer in memory.
/// </summary>
public unsafe class Buffer : NativeObject
{
public const int DefaultReplacementCodepoint = '\uFFFD';
Expand All @@ -16,6 +19,9 @@ internal Buffer (IntPtr handle)
{
}

/// <summary>
/// Creates a new <see cref="Buffer" /> with default values.
/// </summary>
public Buffer ()
: this (HarfBuzzApi.hb_buffer_create ())
{
Expand All @@ -26,6 +32,12 @@ public ContentType ContentType {
set => HarfBuzzApi.hb_buffer_set_content_type (Handle, value);
}

/// <summary>
/// Get or sets the text flow direction of the buffer.
/// </summary>
/// <remarks>
/// No shaping can happen without setting the direction, or invoking <see cref="Buffer.GuessSegmentProperties" />.
/// </remarks>
public Direction Direction {
get => HarfBuzzApi.hb_buffer_get_direction (Handle);
set => HarfBuzzApi.hb_buffer_set_direction (Handle, value);
Expand Down Expand Up @@ -61,6 +73,12 @@ public Script Script {
set => HarfBuzzApi.hb_buffer_set_script (Handle, value);
}

/// <summary>
/// Gets or sets the size of the buffer.
/// </summary>
/// <remarks>
/// If the new length is greater that the current length, more memory will be allocated. If the new length is less than the current length, the extra items will be cleared.
/// </remarks>
public int Length {
get => (int)HarfBuzzApi.hb_buffer_get_length (Handle);
set => HarfBuzzApi.hb_buffer_set_length (Handle, (uint)value);
Expand All @@ -71,6 +89,12 @@ public UnicodeFunctions UnicodeFunctions {
set => HarfBuzzApi.hb_buffer_set_unicode_funcs (Handle, value.Handle);
}

/// <summary>
/// Gets the buffer glyph information array.
/// </summary>
/// <remarks>
/// The information is valid as long as buffer contents are not modified.
/// </remarks>
public GlyphInfo[] GlyphInfos {
get {
var array = GetGlyphInfoSpan ().ToArray ();
Expand All @@ -79,6 +103,12 @@ public GlyphInfo[] GlyphInfos {
}
}

/// <summary>
/// Gets the buffer glyph position array.
/// </summary>
/// <remarks>
/// The positions are valid as long as buffer contents are not modified.
/// </remarks>
public GlyphPosition[] GlyphPositions {
get {
var array = GetGlyphPositionSpan ().ToArray ();
Expand All @@ -89,6 +119,14 @@ public GlyphPosition[] GlyphPositions {

public void Add (int codepoint, int cluster) => Add ((uint)codepoint, (uint)cluster);

/// <summary>
/// Appends a character with the Unicode value and gives it the initial cluster value.
/// </summary>
/// <param name="codepoint">The Unicode code point.</param>
/// <param name="cluster">The cluster value of the code point.</param>
/// <remarks>
/// This function does not check the validity of the codepoint.
/// </remarks>
public void Add (uint codepoint, uint cluster)
{
if (Length != 0 && ContentType != ContentType.Unicode)
Expand All @@ -99,8 +137,16 @@ public void Add (uint codepoint, uint cluster)
HarfBuzzApi.hb_buffer_add (Handle, codepoint, cluster);
}

/// <summary>
/// Appends the specified text to the buffer.
/// </summary>
/// <param name="utf8text">The array of UTF-8 characters to append.</param>
public void AddUtf8 (string utf8text) => AddUtf8 (Encoding.UTF8.GetBytes (utf8text), 0, -1);

/// <summary>
/// Appends the specified text bytes to the buffer.
/// </summary>
/// <param name="bytes">The array of UTF-8 character bytes to append.</param>
public void AddUtf8 (byte[] bytes) => AddUtf8 (new ReadOnlySpan<byte> (bytes));

public void AddUtf8 (ReadOnlySpan<byte> text) => AddUtf8 (text, 0, -1);
Expand Down Expand Up @@ -208,6 +254,13 @@ public void AddUtf32 (IntPtr text, int textLength, int itemOffset, int itemLengt
HarfBuzzApi.hb_buffer_add_utf32 (Handle, (uint*)text, textLength, (uint)itemOffset, itemLength);
}

/// <summary>
/// Appends characters from the span to the buffer.
/// </summary>
/// <param name="text">The span of Unicode code points to append.</param>
/// <remarks>
/// This function does not check the validity of the characters.
/// </remarks>
public void AddCodepoints (ReadOnlySpan<uint> text) => AddCodepoints (text, 0, -1);

public unsafe void AddCodepoints (ReadOnlySpan<uint> text, int itemOffset, int itemLength)
Expand Down Expand Up @@ -254,6 +307,9 @@ public unsafe ReadOnlySpan<GlyphPosition> GetGlyphPositionSpan ()
return new ReadOnlySpan<GlyphPosition> (infoPtrs, (int)length);
}

/// <summary>
/// Sets the unset buffer segment properties based on the buffer's Unicode contents.
/// </summary>
public void GuessSegmentProperties ()
{
if (ContentType != ContentType.Unicode)
Expand All @@ -262,6 +318,12 @@ public void GuessSegmentProperties ()
HarfBuzzApi.hb_buffer_guess_segment_properties (Handle);
}

/// <summary>
/// Clears the buffer's contents.
/// </summary>
/// <remarks>
/// This operation preserves the Unicode functions and replacement code point.
/// </remarks>
public void ClearContents () => HarfBuzzApi.hb_buffer_clear_contents (Handle);

public void Reset () => HarfBuzzApi.hb_buffer_reset (Handle);
Expand Down
6 changes: 6 additions & 0 deletions binding/HarfBuzzSharp/Definitions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@

namespace HarfBuzzSharp
{
/// <summary>
/// Represents a glyph and its relation to the input text.
/// </summary>
public unsafe partial struct GlyphInfo
{
/// <summary>
/// Gets the <see cref="GlyphFlags" /> for this instance.
/// </summary>
public GlyphFlags GlyphFlags {
get {
fixed (GlyphInfo* f = &this) {
Expand Down
3 changes: 3 additions & 0 deletions binding/HarfBuzzSharp/DelegateProxies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

namespace HarfBuzzSharp
{
/// <summary>
/// The delegate that will be invoked when a resource is ready to be discarded.
/// </summary>
public delegate void ReleaseDelegate ();

public delegate Blob GetTableDelegate (Face face, Tag tag);
Expand Down
14 changes: 14 additions & 0 deletions binding/HarfBuzzSharp/DelegateProxies.font.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@

namespace HarfBuzzSharp
{
/// <summary>
/// The delegate that is invoked when <see cref="Font.TryGetHorizontalFontExtents(out HarfBuzzSharp.FontExtents)" /> or <see cref="Font.TryGetVerticalFontExtents(out HarfBuzzSharp.FontExtents)" /> is invoked.
/// </summary>
/// <param name="font">The font.</param>
/// <param name="fontData">The additional data passed to <see cref="Font.SetFontFunctions(HarfBuzzSharp.FontFunctions,System.Object,HarfBuzzSharp.ReleaseDelegate)" /> when the functions were set.</param>
/// <param name="extents">The font extents.</param>
/// <returns>Return true if the <see cref="Font" /> has extents, otherwise false.</returns>
public delegate bool FontExtentsDelegate (Font font, object fontData, out FontExtents extents);

public delegate bool NominalGlyphDelegate (Font font, object fontData, uint unicode, out uint glyph);
Expand All @@ -13,6 +20,13 @@ namespace HarfBuzzSharp

public delegate bool VariationGlyphDelegate (Font font, object fontData, uint unicode, uint variationSelector, out uint glyph);

/// <summary>
/// The delegate that is invoked when <see cref="Font.GetHorizontalGlyphAdvance(System.UInt32)" /> or <see cref="Font.GetVerticalGlyphAdvance(System.UInt32)" /> is invoked.
/// </summary>
/// <param name="font">The font.</param>
/// <param name="fontData">The additional data passed to <see cref="Font.SetFontFunctions(HarfBuzzSharp.FontFunctions,System.Object,HarfBuzzSharp.ReleaseDelegate)" /> when the functions were set.</param>
/// <param name="glyph">The glyph.</param>
/// <returns>Return the advance amount.</returns>
public delegate int GlyphAdvanceDelegate (Font font, object fontData, uint glyph);

public delegate void GlyphAdvancesDelegate (Font font, object fontData, uint count, ReadOnlySpan<uint> glyphs, Span<int> advances);
Expand Down
26 changes: 26 additions & 0 deletions binding/HarfBuzzSharp/Face.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,33 @@

namespace HarfBuzzSharp
{
/// <summary>
/// Represents a typeface.
/// </summary>
public unsafe class Face : NativeObject
{
private static readonly Lazy<Face> emptyFace = new Lazy<Face> (() => new StaticFace (HarfBuzzApi.hb_face_get_empty ()));

/// <summary>
/// Gets a reference to the empty <see cref="Face" /> instance.
/// </summary>
public static Face Empty => emptyFace.Value;

/// <summary>
/// Creates a new <see cref="Face" /> instance, using the specified typeface blob.
/// </summary>
/// <param name="blob">The typeface data.</param>
/// <param name="index">The zero-based face index in a collection.</param>
public Face (Blob blob, uint index)
: this (blob, (int)index)
{
}

/// <summary>
/// Creates a new <see cref="Face" /> instance, using the specified typeface blob.
/// </summary>
/// <param name="blob">The typeface data.</param>
/// <param name="index">The zero-based face index in a collection.</param>
public Face (Blob blob, int index)
: this (IntPtr.Zero)
{
Expand All @@ -29,6 +45,10 @@ public Face (Blob blob, int index)
Handle = HarfBuzzApi.hb_face_create (blob.Handle, (uint)index);
}

/// <summary>
/// Creates a new <see cref="Face" /> instance, using the delegate to assemble the data.
/// </summary>
/// <param name="getTable">The delegate to retrieve the table data.</param>
public Face (GetTableDelegate getTable)
: this (getTable, null)
{
Expand All @@ -51,11 +71,17 @@ internal Face (IntPtr handle)
{
}

/// <summary>
/// Gets or sets the zero-based face index in a collection.
/// </summary>
public int Index {
get => (int)HarfBuzzApi.hb_face_get_index (Handle);
set => HarfBuzzApi.hb_face_set_index (Handle, (uint)value);
}

/// <summary>
/// Gets or sets the units per EM.
/// </summary>
public int UnitsPerEm {
get => (int)HarfBuzzApi.hb_face_get_upem (Handle);
set => HarfBuzzApi.hb_face_set_upem (Handle, (uint)value);
Expand Down
Loading