Update with recovered code from VM binaries (Jan 1)

Recovered from decompiled OpenMaui.Controls.Linux.dll:
- SkiaShell.cs: FlyoutHeader, FlyoutFooter, scroll support (918 -> 1325 lines)
- X11Window.cs: Cursor support (XCreateFontCursor, XDefineCursor)
- All handlers with dark mode support
- All services with latest implementations
- LinuxApplication with theme change handling
This commit is contained in:
2026-01-01 06:22:48 -05:00
parent 1e84c6168a
commit 1f096c38dc
254 changed files with 49359 additions and 38457 deletions

View File

@@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SkiaSharp;
namespace Microsoft.Maui.Platform.Linux.Rendering;
public class TextRenderCache : IDisposable
{
private readonly struct TextCacheKey : IEquatable<TextCacheKey>
{
private readonly string _text;
private readonly float _textSize;
private readonly SKColor _color;
private readonly int _weight;
private readonly int _hashCode;
public TextCacheKey(string text, SKPaint paint)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
_text = text;
_textSize = paint.TextSize;
_color = paint.Color;
SKTypeface typeface = paint.Typeface;
_weight = ((typeface != null) ? typeface.FontWeight : 400);
_hashCode = HashCode.Combine<string, float, SKColor, int>(_text, _textSize, _color, _weight);
}
public bool Equals(TextCacheKey other)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
if (_text == other._text && Math.Abs(_textSize - other._textSize) < 0.001f && _color == other._color)
{
return _weight == other._weight;
}
return false;
}
public override bool Equals(object? obj)
{
if (obj is TextCacheKey other)
{
return Equals(other);
}
return false;
}
public override int GetHashCode()
{
return _hashCode;
}
}
private readonly Dictionary<TextCacheKey, SKBitmap> _cache = new Dictionary<TextCacheKey, SKBitmap>();
private readonly object _lock = new object();
private int _maxEntries = 500;
private bool _disposed;
public int MaxEntries
{
get
{
return _maxEntries;
}
set
{
_maxEntries = Math.Max(10, value);
}
}
public SKBitmap GetOrCreate(string text, SKPaint paint)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Expected O, but got Unknown
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
TextCacheKey key = new TextCacheKey(text, paint);
lock (_lock)
{
if (_cache.TryGetValue(key, out SKBitmap value))
{
return value;
}
SKRect val = default(SKRect);
paint.MeasureText(text, ref val);
int num = Math.Max(1, (int)Math.Ceiling(((SKRect)(ref val)).Width) + 2);
int num2 = Math.Max(1, (int)Math.Ceiling(((SKRect)(ref val)).Height) + 2);
SKBitmap val2 = new SKBitmap(num, num2, (SKColorType)4, (SKAlphaType)2);
SKCanvas val3 = new SKCanvas(val2);
try
{
val3.Clear(SKColors.Transparent);
val3.DrawText(text, 0f - ((SKRect)(ref val)).Left + 1f, 0f - ((SKRect)(ref val)).Top + 1f, paint);
}
finally
{
((IDisposable)val3)?.Dispose();
}
if (_cache.Count >= _maxEntries)
{
KeyValuePair<TextCacheKey, SKBitmap> keyValuePair = _cache.First();
((SKNativeObject)keyValuePair.Value).Dispose();
_cache.Remove(keyValuePair.Key);
}
_cache[key] = val2;
return val2;
}
}
public void Clear()
{
lock (_lock)
{
foreach (SKBitmap value in _cache.Values)
{
((SKNativeObject)value).Dispose();
}
_cache.Clear();
}
}
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
Clear();
}
}
}