Skip to content

Conversation

@Gillibald
Copy link
Contributor

What does the pull request do?

What is the current behavior?

What is the updated/expected behavior with this PR?

How was the solution implemented (if it's not obvious)?

Checklist

Breaking changes

Obsoletions / Deprecations

Fixed issues

@maxkatz6 maxkatz6 added enhancement breaking-change area-textprocessing needs-api-review The PR adds new public APIs that should be reviewed. labels Oct 18, 2025
@Gillibald
Copy link
Contributor Author

Avalonia.Base (net6.0, net8.0, netstandard2.0)

  namespace Avalonia.Media
  {
      public interface IGlyphTypeface
      {
-         ushort GetGlyph(uint codepoint);
-         int GetGlyphAdvance(ushort glyph);
+         ushort GetGlyphAdvance(ushort glyph);
-         int[] GetGlyphAdvances(System.ReadOnlySpan<ushort> glyphs);
-         ushort[] GetGlyphs(System.ReadOnlySpan<uint> codepoints);
-         bool TryGetGlyph(uint codepoint, out ushort glyph);
-         bool TryGetTable(uint tag, out byte[] table);
-         int GlyphCount { get; }
+         uint GlyphCount { get; }
+         System.Collections.Generic.IReadOnlyDictionary<int, ushort> CharacterToGlyphMap { get; }
+         System.Collections.Generic.IReadOnlyDictionary<System.Globalization.CultureInfo, string> FaceNames { get; }
+         System.Collections.Generic.IReadOnlyDictionary<System.Globalization.CultureInfo, string> FamilyNames { get; }
+         Avalonia.Media.IPlatformTypeface PlatformTypeface { get; }
+         System.Collections.Generic.IReadOnlyList<Avalonia.Media.Fonts.OpenTypeTag> SupportedFeatures { get; }
+         Avalonia.Media.ITextShaperTypeface TextShaperTypeface { get; }
+         string TypographicFamilyName { get; }
      }
+     public interface IFontMemory
+     {
+         bool TryGetTable(Avalonia.Media.Fonts.OpenTypeTag tag, out System.ReadOnlyMemory<byte> table);
+     }
+     public interface IPlatformTypeface : Avalonia.Media.IFontMemory
+     {
+         bool? TryGetStream(out System.IO.Stream? stream);
+     }
+     public interface ITextShaperTypeface
+     {
+     }
  }
  namespace Avalonia.Media.Fonts
  {
+     public sealed class OpenTypeTag
+     {
+         public static readonly Avalonia.Media.Fonts.OpenTypeTag Max;
+         public static readonly Avalonia.Media.Fonts.OpenTypeTag MaxSigned;
+         public static readonly Avalonia.Media.Fonts.OpenTypeTag None;
+         public OpenTypeTag(char c1, char c2, char c3, char c4);
+         public OpenTypeTag(uint value);
+         public bool Equals(Avalonia.Media.Fonts.OpenTypeTag other);
+         public override bool Equals(object obj);
+         public override int GetHashCode();
+         public static bool operator ==(Avalonia.Media.Fonts.OpenTypeTag left, Avalonia.Media.Fonts.OpenTypeTag right);
+         public static implicit operator uint(Avalonia.Media.Fonts.OpenTypeTag tag);
+         public static implicit operator Avalonia.Media.Fonts.OpenTypeTag(uint tag);
+         public static bool operator !=(Avalonia.Media.Fonts.OpenTypeTag left, Avalonia.Media.Fonts.OpenTypeTag right);
+         public static Avalonia.Media.Fonts.OpenTypeTag Parse(string tag);
+         public override string ToString();
+     }
  }
  namespace Avalonia.Platform
  {
      public interface IFontManagerImpl
      {
+         bool TryGetFamilyTypefaces(string familyName, out System.Collections.Generic.IReadOnlyList<Avalonia.Media.Typeface?>? familyTypefaces);
      }
      public interface IGlyphRunImpl
      {
-         Avalonia.Media.IGlyphTypeface GlyphTypeface { get; }
      }
      public interface ITextShaperImpl
      {
+         Avalonia.Media.ITextShaperTypeface CreateTypeface(Avalonia.Media.IGlyphTypeface glyphTypeface);
      }
  }

@Gillibald Gillibald requested a review from Copilot October 22, 2025 13:00
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a universal GlyphTypeface implementation that abstracts platform-specific font handling through new interfaces (IPlatformTypeface, ITextShaperTypeface, IFontMemory). The changes consolidate glyph typeface functionality, moving from direct platform implementations to a unified architecture.

Key changes:

  • Introduced new interfaces to separate platform-specific font operations from the core IGlyphTypeface interface
  • Replaced direct method calls like GetGlyph() with a CharacterToGlyphMap dictionary lookup
  • Implemented OpenType table parsing classes for CMAP, metrics, and other font tables

Reviewed Changes

Copilot reviewed 68 out of 70 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Avalonia.Base/Media/IGlyphTypeface.cs Expanded interface with new properties and removed deprecated methods; added IPlatformTypeface, ITextShaperTypeface, IFontMemory interfaces
src/Avalonia.Base/Media/GlyphTypeface.cs New universal implementation using platform typeface abstraction and OpenType table parsing
src/Avalonia.Base/Media/Fonts/Tables/Cmap/*.cs Added CMAP table parsing for character-to-glyph mapping
src/Skia/Avalonia.Skia/SkiaTypeface.cs New platform-specific implementation for Skia
src/Windows/Avalonia.Direct2D1/Media/DWriteTypeface.cs New platform-specific implementation for DirectWrite
src/Avalonia.Base/Media/Fonts/Tables/BigEndianBinaryReader.cs Converted from stream-based to span-based for better performance
tests/* Updated to use CharacterToGlyphMap instead of GetGlyph()

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@avaloniaui-bot
Copy link

You can test this PR using the following package version. 12.0.999-cibuild0059491-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-textprocessing breaking-change enhancement needs-api-review The PR adds new public APIs that should be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants