Skip to content

Commit 556ed2f

Browse files
committed
重构字体诊断信息为 LvglFontDiagnostics 结构体
统一字体诊断信息的管理方式,引入 LvglFontDiagnostics 结构体,替换原有的字符串字段,简化了诊断信息的传递与释放接口。各 View 及相关 Helper 方法均改为使用结构化的诊断信息,并统一 ToString 输出格式。提升了代码的可维护性和诊断一致性。
1 parent 452ec0b commit 556ed2f

File tree

17 files changed

+421
-279
lines changed

17 files changed

+421
-279
lines changed

src/LVGLSharp.Core/LVGLSharp.Core.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@
2424
<ProjectReference Include="..\LVGLSharp.Interop\LVGLSharp.Interop.csproj" />
2525
</ItemGroup>
2626

27+
<ItemGroup>
28+
<Folder Include="Drawing\" />
29+
</ItemGroup>
30+
2731
</Project>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using SixLabors.Fonts;
2+
3+
namespace LVGLSharp;
4+
5+
public readonly record struct LvglFontDiagnostics(
6+
string? ResolvedFontPath,
7+
string? DiagnosticSummary,
8+
string? GlyphDiagnosticSummary)
9+
{
10+
public string DisplayResolvedFontPath => string.IsNullOrWhiteSpace(ResolvedFontPath) ? "<none>" : ResolvedFontPath;
11+
12+
public string DisplaySummary => string.IsNullOrWhiteSpace(DiagnosticSummary) ? "<unresolved>" : DiagnosticSummary;
13+
14+
public string DisplayGlyphSummary => string.IsNullOrWhiteSpace(GlyphDiagnosticSummary) ? "<unresolved>" : GlyphDiagnosticSummary;
15+
16+
public static LvglFontDiagnostics Empty => default;
17+
18+
public static LvglFontDiagnostics FromPath(string? resolvedFontPath, string? diagnosticSummary, string? glyphDiagnosticSummary)
19+
{
20+
return new LvglFontDiagnostics(resolvedFontPath, diagnosticSummary, glyphDiagnosticSummary);
21+
}
22+
23+
public static LvglFontDiagnostics FromFontFamily(FontFamily? fontFamily, IEnumerable<string> candidates, bool enabled)
24+
{
25+
ArgumentNullException.ThrowIfNull(candidates);
26+
27+
if (!enabled)
28+
{
29+
return new LvglFontDiagnostics(null, "ManagedFontDisabled", null);
30+
}
31+
32+
var candidateList = string.Join(", ", candidates.Where(static candidate => !string.IsNullOrWhiteSpace(candidate)));
33+
if (fontFamily is null)
34+
{
35+
return new LvglFontDiagnostics(null, $"ManagedFontEnabled; Family=<none>; Candidates={candidateList}", null);
36+
}
37+
38+
return new LvglFontDiagnostics(
39+
fontFamily.Value.Name,
40+
$"ManagedFontEnabled; Family={fontFamily.Value.Name}; Candidates={candidateList}",
41+
null);
42+
}
43+
}

src/LVGLSharp.Core/LvglManagedFontHelper.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,47 @@ public static bool TryResolveFontFamily(IEnumerable<string> fontFamilyNames, out
5050
return false;
5151
}
5252

53+
/// <summary>
54+
/// Initializes managed font state from a resolved font file path.
55+
/// </summary>
56+
public static LvglManagedFontState InitializeManagedFont(
57+
lv_obj_t* root,
58+
string? fontPath,
59+
float size,
60+
float dpi,
61+
LvglFontDiagnostics diagnostics,
62+
bool enabled)
63+
{
64+
var fallbackFont = LvglFontHelper.GetEffectiveTextFont(root, lv_part_t.LV_PART_MAIN);
65+
var fontManager = TryApplyManagedFont(root, fontPath, size, dpi, fallbackFont, out var font, out var style, enabled);
66+
return new LvglManagedFontState(fallbackFont, font, fontManager, diagnostics, style);
67+
}
68+
69+
/// <summary>
70+
/// Initializes managed font state from a resolved font family.
71+
/// </summary>
72+
public static LvglManagedFontState InitializeManagedFont(
73+
lv_obj_t* root,
74+
FontFamily? fontFamily,
75+
IEnumerable<string> fontFamilyNames,
76+
float size,
77+
float dpi,
78+
bool enabled)
79+
{
80+
var diagnostics = CreateFontDiagnostics(fontFamily, fontFamilyNames, enabled);
81+
var fallbackFont = LvglFontHelper.GetEffectiveTextFont(root, lv_part_t.LV_PART_MAIN);
82+
var fontManager = TryApplyManagedFont(root, fontFamily, size, dpi, fallbackFont, out var font, out var style, enabled);
83+
return new LvglManagedFontState(fallbackFont, font, fontManager, diagnostics, style);
84+
}
85+
86+
/// <summary>
87+
/// Creates a shared diagnostics model for managed font family resolution.
88+
/// </summary>
89+
public static LvglFontDiagnostics CreateFontDiagnostics(FontFamily? fontFamily, IEnumerable<string> fontFamilyNames, bool enabled)
90+
{
91+
return LvglFontDiagnostics.FromFontFamily(fontFamily, fontFamilyNames, enabled);
92+
}
93+
5394
/// <summary>
5495
/// Applies a managed font from the specified font file path when managed fonts are enabled.
5596
/// </summary>
@@ -127,4 +168,31 @@ public static void ReleaseManagedFont(
127168
lv_font_t* font = null;
128169
ReleaseManagedFont(ref fallbackFont, ref font, ref fontManager, ref defaultFontStyle);
129170
}
171+
172+
/// <summary>
173+
/// Releases managed font state and diagnostics.
174+
/// </summary>
175+
public static void ReleaseManagedFont(
176+
ref lv_font_t* fallbackFont,
177+
ref lv_font_t* font,
178+
ref SixLaborsFontManager? fontManager,
179+
ref LvglFontDiagnostics diagnostics,
180+
ref lv_style_t* defaultFontStyle)
181+
{
182+
ReleaseManagedFont(ref fallbackFont, ref font, ref fontManager, ref defaultFontStyle);
183+
diagnostics = LvglFontDiagnostics.Empty;
184+
}
185+
186+
/// <summary>
187+
/// Releases managed font state and diagnostics.
188+
/// </summary>
189+
public static void ReleaseManagedFont(
190+
ref lv_font_t* fallbackFont,
191+
ref SixLaborsFontManager? fontManager,
192+
ref LvglFontDiagnostics diagnostics,
193+
ref lv_style_t* defaultFontStyle)
194+
{
195+
lv_font_t* font = null;
196+
ReleaseManagedFont(ref fallbackFont, ref font, ref fontManager, ref diagnostics, ref defaultFontStyle);
197+
}
130198
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using LVGLSharp.Interop;
2+
3+
namespace LVGLSharp;
4+
5+
/// <summary>
6+
/// Represents the managed font state applied to an LVGL root object.
7+
/// </summary>
8+
public readonly unsafe struct LvglManagedFontState
9+
{
10+
internal LvglManagedFontState(
11+
lv_font_t* fallbackFont,
12+
lv_font_t* managedFont,
13+
SixLaborsFontManager? fontManager,
14+
LvglFontDiagnostics diagnostics,
15+
lv_style_t* defaultFontStyle)
16+
{
17+
FallbackFont = fallbackFont;
18+
ManagedFont = managedFont;
19+
FontManager = fontManager;
20+
Diagnostics = diagnostics;
21+
DefaultFontStyle = defaultFontStyle;
22+
}
23+
24+
public static LvglManagedFontState Empty => default;
25+
26+
public lv_font_t* FallbackFont { get; }
27+
28+
public lv_font_t* ManagedFont { get; }
29+
30+
public SixLaborsFontManager? FontManager { get; }
31+
32+
public LvglFontDiagnostics Diagnostics { get; }
33+
34+
public lv_style_t* DefaultFontStyle { get; }
35+
36+
public void ApplyTo(
37+
ref lv_font_t* fallbackFont,
38+
ref SixLaborsFontManager? fontManager,
39+
ref lv_style_t* defaultFontStyle)
40+
{
41+
fallbackFont = FallbackFont;
42+
fontManager = FontManager;
43+
defaultFontStyle = DefaultFontStyle;
44+
}
45+
46+
public void ApplyTo(
47+
ref lv_font_t* fallbackFont,
48+
ref SixLaborsFontManager? fontManager,
49+
ref LvglFontDiagnostics diagnostics,
50+
ref lv_style_t* defaultFontStyle)
51+
{
52+
ApplyTo(ref fallbackFont, ref fontManager, ref defaultFontStyle);
53+
diagnostics = Diagnostics;
54+
}
55+
56+
public void ApplyTo(
57+
ref lv_font_t* fallbackFont,
58+
ref lv_font_t* managedFont,
59+
ref SixLaborsFontManager? fontManager,
60+
ref LvglFontDiagnostics diagnostics,
61+
ref lv_style_t* defaultFontStyle)
62+
{
63+
ApplyTo(ref fallbackFont, ref fontManager, ref diagnostics, ref defaultFontStyle);
64+
managedFont = ManagedFont;
65+
}
66+
}

src/LVGLSharp.Drawing/Color.cs

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,100 @@ namespace LVGLSharp.Drawing;
22

33
public readonly struct Color : IEquatable<Color>
44
{
5+
private readonly string? _name;
6+
57
public Color(byte r, byte g, byte b, byte a = 255)
8+
: this(a, r, g, b, null)
9+
{
10+
}
11+
12+
private Color(byte a, byte r, byte g, byte b, string? name)
613
{
714
A = a;
815
R = r;
916
G = g;
1017
B = b;
18+
_name = name;
1119
}
1220

1321
public byte A { get; }
22+
1423
public byte R { get; }
24+
1525
public byte G { get; }
26+
1627
public byte B { get; }
1728

18-
public static Color Empty => new(0, 0, 0, 0);
29+
public bool IsEmpty => A == 0 && R == 0 && G == 0 && B == 0 && _name is null;
30+
31+
public string Name => _name ?? (IsEmpty ? nameof(Empty) : ToArgb().ToString("X8"));
32+
33+
public static Color Empty => default;
1934

20-
public bool Equals(Color other) => A == other.A && R == other.R && G == other.G && B == other.B;
35+
public static Color Transparent => new(0, 255, 255, 255, nameof(Transparent));
36+
37+
public static Color Black => new(255, 0, 0, 0, nameof(Black));
38+
39+
public static Color White => new(255, 255, 255, 255, nameof(White));
40+
41+
public static Color Red => new(255, 255, 0, 0, nameof(Red));
42+
43+
public static Color Green => new(255, 0, 128, 0, nameof(Green));
44+
45+
public static Color Blue => new(255, 0, 0, 255, nameof(Blue));
46+
47+
public static Color FromArgb(int red, int green, int blue)
48+
{
49+
return FromArgb(255, red, green, blue);
50+
}
51+
52+
public static Color FromArgb(int alpha, int red, int green, int blue)
53+
{
54+
return new Color(ToByte(alpha), ToByte(red), ToByte(green), ToByte(blue), null);
55+
}
56+
57+
public static Color FromArgb(int alpha, Color baseColor)
58+
{
59+
return new Color(ToByte(alpha), baseColor.R, baseColor.G, baseColor.B, baseColor._name);
60+
}
61+
62+
public static Color FromName(string name)
63+
{
64+
ArgumentException.ThrowIfNullOrWhiteSpace(name);
65+
66+
return name switch
67+
{
68+
nameof(Transparent) => Transparent,
69+
nameof(Black) => Black,
70+
nameof(White) => White,
71+
nameof(Red) => Red,
72+
nameof(Green) => Green,
73+
nameof(Blue) => Blue,
74+
_ => new Color(0, 0, 0, 0, name),
75+
};
76+
}
77+
78+
public int ToArgb()
79+
{
80+
return (A << 24) | (R << 16) | (G << 8) | B;
81+
}
82+
83+
public bool Equals(Color other) => A == other.A && R == other.R && G == other.G && B == other.B && string.Equals(_name, other._name, StringComparison.Ordinal);
2184

2285
public override bool Equals(object? obj) => obj is Color other && Equals(other);
2386

24-
public override int GetHashCode() => HashCode.Combine(A, R, G, B);
87+
public override int GetHashCode() => HashCode.Combine(A, R, G, B, _name);
88+
89+
public override string ToString() => Name;
2590

2691
public static bool operator ==(Color left, Color right) => left.Equals(right);
2792

2893
public static bool operator !=(Color left, Color right) => !left.Equals(right);
94+
95+
private static byte ToByte(int value)
96+
{
97+
return value < byte.MinValue || value > byte.MaxValue
98+
? throw new ArgumentOutOfRangeException(nameof(value))
99+
: (byte)value;
100+
}
29101
}

src/LVGLSharp.Drawing/Font.cs

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,68 @@
11
namespace LVGLSharp.Drawing;
22

3-
public class Font
3+
public sealed class Font : IEquatable<Font>
44
{
5-
public Font(string name, float size)
5+
public Font(string familyName, float emSize)
6+
: this(familyName, emSize, FontStyle.Regular, GraphicsUnit.Point)
67
{
7-
ArgumentException.ThrowIfNullOrWhiteSpace(name);
8-
Name = name;
9-
Size = size;
8+
}
9+
10+
public Font(string familyName, float emSize, FontStyle style)
11+
: this(familyName, emSize, style, GraphicsUnit.Point)
12+
{
13+
}
14+
15+
public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit)
16+
{
17+
ArgumentException.ThrowIfNullOrWhiteSpace(familyName);
18+
if (emSize <= 0)
19+
{
20+
throw new ArgumentOutOfRangeException(nameof(emSize));
21+
}
22+
23+
Name = familyName;
24+
Size = emSize;
25+
Style = style;
26+
Unit = unit;
1027
}
1128

1229
public string Name { get; }
1330

1431
public float Size { get; }
32+
33+
public float SizeInPoints => Unit == GraphicsUnit.Point ? Size : Size;
34+
35+
public FontStyle Style { get; }
36+
37+
public GraphicsUnit Unit { get; }
38+
39+
public bool Bold => (Style & FontStyle.Bold) != 0;
40+
41+
public bool Italic => (Style & FontStyle.Italic) != 0;
42+
43+
public bool Underline => (Style & FontStyle.Underline) != 0;
44+
45+
public bool Strikeout => (Style & FontStyle.Strikeout) != 0;
46+
47+
public FontFamily FontFamily => new(Name);
48+
49+
public Font WithSize(float emSize)
50+
{
51+
return new Font(Name, emSize, Style, Unit);
52+
}
53+
54+
public bool Equals(Font? other)
55+
{
56+
return other is not null &&
57+
string.Equals(Name, other.Name, StringComparison.Ordinal) &&
58+
Size.Equals(other.Size) &&
59+
Style == other.Style &&
60+
Unit == other.Unit;
61+
}
62+
63+
public override bool Equals(object? obj) => obj is Font other && Equals(other);
64+
65+
public override int GetHashCode() => HashCode.Combine(Name, Size, Style, Unit);
66+
67+
public override string ToString() => $"[{Name}, {SizeInPoints}pt]";
1568
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace LVGLSharp.Drawing;
2+
3+
public sealed class FontFamily : IEquatable<FontFamily>
4+
{
5+
public FontFamily(string name)
6+
{
7+
ArgumentException.ThrowIfNullOrWhiteSpace(name);
8+
Name = name;
9+
}
10+
11+
public string Name { get; }
12+
13+
public bool Equals(FontFamily? other) => other is not null && string.Equals(Name, other.Name, StringComparison.Ordinal);
14+
15+
public override bool Equals(object? obj) => obj is FontFamily other && Equals(other);
16+
17+
public override int GetHashCode() => StringComparer.Ordinal.GetHashCode(Name);
18+
19+
public override string ToString() => Name;
20+
}

0 commit comments

Comments
 (0)