123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- using System;
- using System.IO;
- using Avalonia.Media;
- using HarfBuzzSharp;
- namespace Avalonia.UnitTests
- {
- public class HarfBuzzGlyphTypefaceImpl : IGlyphTypeface
- {
- private bool _isDisposed;
- private Blob _blob;
- public HarfBuzzGlyphTypefaceImpl(Stream data)
- {
- _blob = Blob.FromStream(data);
-
- Face = new Face(_blob, 0);
- Font = new Font(Face);
- Font.SetFunctionsOpenType();
- Font.GetScale(out var scale, out _);
- const double defaultFontRenderingEmSize = 12.0;
- var metrics = Font.OpenTypeMetrics;
- Metrics = new FontMetrics
- {
- DesignEmHeight = (short)scale,
- Ascent = (int)(metrics.GetXVariation(OpenTypeMetricsTag.HorizontalAscender) / defaultFontRenderingEmSize * scale),
- Descent = (int)(metrics.GetXVariation(OpenTypeMetricsTag.HorizontalDescender) / defaultFontRenderingEmSize * scale),
- LineGap = (int)(metrics.GetXVariation(OpenTypeMetricsTag.HorizontalLineGap) / defaultFontRenderingEmSize * scale),
- UnderlinePosition = (int)(metrics.GetXVariation(OpenTypeMetricsTag.UnderlineOffset) / defaultFontRenderingEmSize * scale),
- UnderlineThickness = (int)(metrics.GetXVariation(OpenTypeMetricsTag.UnderlineSize) / defaultFontRenderingEmSize * scale),
- StrikethroughPosition = (int)(metrics.GetXVariation(OpenTypeMetricsTag.StrikeoutOffset) / defaultFontRenderingEmSize * scale),
- StrikethroughThickness = (int)(metrics.GetXVariation(OpenTypeMetricsTag.StrikeoutSize) / defaultFontRenderingEmSize * scale),
- IsFixedPitch = GetGlyphAdvance(GetGlyph('a')) == GetGlyphAdvance(GetGlyph('b'))
- };
- GlyphCount = Face.GlyphCount;
- }
- public FontMetrics Metrics { get; }
- public Face Face { get; }
- public Font Font { get; }
- public int GlyphCount { get; set; }
- public FontSimulations FontSimulations { get; }
- public string FamilyName => "$Default";
- public FontWeight Weight { get; }
- public FontStyle Style { get; }
- public FontStretch Stretch { get; }
- /// <inheritdoc cref="IGlyphTypeface"/>
- public ushort GetGlyph(uint codepoint)
- {
- if (Font.TryGetGlyph(codepoint, out var glyph))
- {
- return (ushort)glyph;
- }
- return 0;
- }
- public bool TryGetGlyph(uint codepoint,out ushort glyph)
- {
- glyph = 0;
- if (Font.TryGetGlyph(codepoint, out var glyphId))
- {
- glyph = (ushort)glyphId;
- return true;
- }
- return false;
- }
- /// <inheritdoc cref="IGlyphTypeface"/>
- public ushort[] GetGlyphs(ReadOnlySpan<uint> codepoints)
- {
- var glyphs = new ushort[codepoints.Length];
- for (var i = 0; i < codepoints.Length; i++)
- {
- if (Font.TryGetGlyph(codepoints[i], out var glyph))
- {
- glyphs[i] = (ushort)glyph;
- }
- }
- return glyphs;
- }
- /// <inheritdoc cref="IGlyphTypeface"/>
- public int GetGlyphAdvance(ushort glyph)
- {
- return Font.GetHorizontalGlyphAdvance(glyph);
- }
- /// <inheritdoc cref="IGlyphTypeface"/>
- public int[] GetGlyphAdvances(ReadOnlySpan<ushort> glyphs)
- {
- var glyphIndices = new uint[glyphs.Length];
- for (var i = 0; i < glyphs.Length; i++)
- {
- glyphIndices[i] = glyphs[i];
- }
- return Font.GetHorizontalGlyphAdvances(glyphIndices);
- }
- public bool TryGetTable(uint tag, out byte[] table)
- {
- table = null;
- var blob = Face.ReferenceTable(tag);
- if (blob.Length > 0)
- {
- table = blob.AsSpan().ToArray();
- return true;
- }
- return false;
- }
- private void Dispose(bool disposing)
- {
- if (_isDisposed)
- {
- return;
- }
- _isDisposed = true;
- if (!disposing)
- {
- return;
- }
- Font?.Dispose();
- Face?.Dispose();
- _blob?.Dispose();
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- public bool TryGetGlyphMetrics(ushort glyph, out GlyphMetrics metrics)
- {
- metrics = default;
- if (!Font.TryGetGlyphExtents(glyph, out var extents))
- {
- return false;
- }
- metrics = new GlyphMetrics
- {
- XBearing = extents.XBearing,
- YBearing = extents.YBearing,
- Width = extents.Width,
- Height = extents.Height
- };
- return true;
- }
- }
- }
|