Skip to content

Commit fa86e9b

Browse files
committed
Merge remote-tracking branch 'origin/stable/0.10.x' into fixes/nullable-avalonia-native
2 parents d06464d + 4a90d96 commit fa86e9b

File tree

6 files changed

+182
-49
lines changed

6 files changed

+182
-49
lines changed

Avalonia.sln

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,6 +2003,30 @@ Global
20032003
{909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhone.Build.0 = Release|Any CPU
20042004
{909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
20052005
{909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
2006+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
2007+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
2008+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
2009+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
2010+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
2011+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
2012+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
2013+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
2014+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
2015+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhone.Build.0 = Debug|Any CPU
2016+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
2017+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
2018+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2019+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|Any CPU.Build.0 = Debug|Any CPU
2020+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
2021+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhone.Build.0 = Debug|Any CPU
2022+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
2023+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
2024+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|Any CPU.ActiveCfg = Release|Any CPU
2025+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|Any CPU.Build.0 = Release|Any CPU
2026+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhone.ActiveCfg = Release|Any CPU
2027+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhone.Build.0 = Release|Any CPU
2028+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
2029+
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
20062030
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
20072031
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
20082032
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU

src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
using System;
22
using System.Globalization;
33
using System.Linq;
4+
using Avalonia.Controls.Presenters;
45
using Avalonia.Input;
6+
using Avalonia.Input.GestureRecognizers;
7+
using Avalonia.Interactivity;
8+
using Avalonia.Media;
59
using Avalonia.VisualTree;
610

711
namespace Avalonia.Controls.Primitives
@@ -58,18 +62,18 @@ public class DateTimePickerPanel : Panel, ILogicalScrollable
5862
private Vector _offset;
5963
private bool _hasInit;
6064
private bool _suppressUpdateOffset;
61-
private ListBoxItem _pressedItem;
65+
private ScrollContentPresenter? _parentScroller;
6266

6367
public DateTimePickerPanel()
6468
{
6569
FormatDate = DateTime.Now;
66-
AddHandler(ListBoxItem.PointerPressedEvent, OnItemPointerDown, Avalonia.Interactivity.RoutingStrategies.Bubble);
67-
AddHandler(ListBoxItem.PointerReleasedEvent, OnItemPointerUp, Avalonia.Interactivity.RoutingStrategies.Bubble);
70+
AddHandler(TappedEvent, OnItemTapped, RoutingStrategies.Bubble);
6871
}
6972

7073
static DateTimePickerPanel()
7174
{
7275
FocusableProperty.OverrideDefaultValue<DateTimePickerPanel>(true);
76+
BackgroundProperty.OverrideDefaultValue<DateTimePickerPanel>(Brushes.Transparent);
7377
AffectsMeasure<DateTimePickerPanel>(ItemHeightProperty);
7478
}
7579

@@ -254,6 +258,8 @@ public Vector Offset
254258
_suppressUpdateOffset = true;
255259
SelectedValue = (int)newSel * Increment + MinimumValue;
256260
_suppressUpdateOffset = false;
261+
262+
System.Diagnostics.Debug.WriteLine($"Offset: {_offset} ItemHeight: {ItemHeight}");
257263
}
258264
}
259265

@@ -269,7 +275,7 @@ public Vector Offset
269275

270276
public Size Extent => _extent;
271277

272-
public Size Viewport => new Size(0, ItemHeight);
278+
public Size Viewport => Bounds.Size;
273279

274280
public event EventHandler ScrollInvalidated;
275281

@@ -340,6 +346,20 @@ protected override Size ArrangeOverride(Size finalSize)
340346
return finalSize;
341347
}
342348

349+
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
350+
{
351+
base.OnAttachedToVisualTree(e);
352+
_parentScroller = this.GetVisualParent() as ScrollContentPresenter;
353+
_parentScroller?.AddHandler(Gestures.ScrollGestureEndedEvent, OnScrollGestureEnded);
354+
}
355+
356+
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
357+
{
358+
base.OnDetachedFromVisualTree(e);
359+
_parentScroller?.RemoveHandler(Gestures.ScrollGestureEndedEvent, OnScrollGestureEnded);
360+
_parentScroller = null;
361+
}
362+
343363
protected override void OnKeyDown(KeyEventArgs e)
344364
{
345365
switch (e.Key)
@@ -523,22 +543,13 @@ private int CoerceSelected(int newValue)
523543
return newValue;
524544
}
525545

526-
private void OnItemPointerDown(object sender, PointerPressedEventArgs e)
546+
private void OnItemTapped(object sender, TappedEventArgs e)
527547
{
528-
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
548+
if (e.Source is IVisual source &&
549+
GetItemFromSource(source) is ListBoxItem listBoxItem &&
550+
listBoxItem.Tag is int tag)
529551
{
530-
_pressedItem = GetItemFromSource((IVisual)e.Source);
531-
e.Handled = true;
532-
}
533-
}
534-
535-
private void OnItemPointerUp(object sender, PointerReleasedEventArgs e)
536-
{
537-
if (e.GetCurrentPoint(this).Properties.PointerUpdateKind == PointerUpdateKind.LeftButtonReleased &&
538-
_pressedItem != null)
539-
{
540-
SelectedValue = (int)GetItemFromSource((IVisual)e.Source).Tag;
541-
_pressedItem = null;
552+
SelectedValue = tag;
542553
e.Handled = true;
543554
}
544555
}
@@ -562,5 +573,15 @@ public void RaiseScrollInvalidated(EventArgs e)
562573
{
563574
ScrollInvalidated?.Invoke(this, e);
564575
}
576+
577+
private void OnScrollGestureEnded(object? sender, ScrollGestureEndedEventArgs e)
578+
{
579+
var snapY = Math.Round(Offset.Y / ItemHeight) * ItemHeight;
580+
581+
if (snapY != Offset.Y)
582+
{
583+
Offset = Offset.WithY(snapY);
584+
}
585+
}
565586
}
566587
}

src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ private void OnScrollGesture(object sender, ScrollGestureEventArgs e)
371371
{
372372
var logicalUnits = delta.Y / logicalScrollItemSize.Y;
373373
delta = delta.WithY(delta.Y - logicalUnits * logicalScrollItemSize.Y);
374-
dy = logicalUnits * scrollable!.ScrollSize.Height;
374+
dy = logicalUnits;
375375
}
376376
else
377377
dy = delta.Y;
@@ -389,7 +389,7 @@ private void OnScrollGesture(object sender, ScrollGestureEventArgs e)
389389
{
390390
var logicalUnits = delta.X / logicalScrollItemSize.X;
391391
delta = delta.WithX(delta.X - logicalUnits * logicalScrollItemSize.X);
392-
dx = logicalUnits * scrollable!.ScrollSize.Width;
392+
dx = logicalUnits;
393393
}
394394
else
395395
dx = delta.X;

src/Skia/Avalonia.Skia/FontManagerImpl.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ public IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = fa
2929
[ThreadStatic] private static string[] t_languageTagBuffer;
3030

3131
public bool TryMatchCharacter(int codepoint, FontStyle fontStyle,
32-
FontWeight fontWeight,
33-
FontFamily fontFamily, CultureInfo culture, out Typeface fontKey)
32+
FontWeight fontWeight, FontFamily fontFamily, CultureInfo culture, out Typeface fontKey)
3433
{
3534
SKFontStyle skFontStyle;
3635

@@ -109,23 +108,31 @@ public IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface)
109108
if (typeface.FontFamily.Key == null)
110109
{
111110
var defaultName = SKTypeface.Default.FamilyName;
112-
var fontStyle = new SKFontStyle((SKFontStyleWeight)typeface.Weight, SKFontStyleWidth.Normal, (SKFontStyleSlant)typeface.Style);
111+
112+
var fontStyle = new SKFontStyle((SKFontStyleWeight)typeface.Weight, SKFontStyleWidth.Normal,
113+
(SKFontStyleSlant)typeface.Style);
113114

114115
foreach (var familyName in typeface.FontFamily.FamilyNames)
115116
{
117+
if(familyName == FontFamily.DefaultFontFamilyName)
118+
{
119+
continue;
120+
}
121+
116122
skTypeface = _skFontManager.MatchFamily(familyName, fontStyle);
117123

118-
if (skTypeface is null
119-
|| (!skTypeface.FamilyName.Equals(familyName, StringComparison.Ordinal)
120-
&& defaultName.Equals(skTypeface.FamilyName, StringComparison.Ordinal)))
124+
if (skTypeface is null || defaultName.Equals(skTypeface.FamilyName, StringComparison.Ordinal))
121125
{
122126
continue;
123127
}
124128

125129
break;
126130
}
127131

128-
skTypeface ??= _skFontManager.MatchTypeface(SKTypeface.Default, fontStyle);
132+
// MatchTypeface can return "null" if matched typeface wasn't found for the style
133+
// Fallback to the default typeface and styles instead.
134+
skTypeface ??= _skFontManager.MatchTypeface(SKTypeface.Default, fontStyle)
135+
?? SKTypeface.Default;
129136
}
130137
else
131138
{
Lines changed: 102 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using System.Collections.Concurrent;
2-
using System.Collections.Generic;
3-
using System.Linq;
42
using Avalonia.Media;
53
using SkiaSharp;
64

@@ -18,48 +16,131 @@ public void AddTypeface(Typeface key, SKTypeface typeface)
1816

1917
public SKTypeface Get(Typeface typeface)
2018
{
21-
return GetNearestMatch(_typefaces, typeface);
19+
return GetNearestMatch(typeface);
2220
}
2321

24-
private static SKTypeface GetNearestMatch(IDictionary<Typeface, SKTypeface> typefaces, Typeface key)
22+
private SKTypeface GetNearestMatch(Typeface key)
2523
{
26-
if (typefaces.TryGetValue(key, out var typeface))
24+
if (_typefaces.Count == 0)
2725
{
28-
return typeface;
26+
return null;
2927
}
3028

31-
var initialWeight = (int)key.Weight;
29+
if (_typefaces.TryGetValue(key, out var typeface))
30+
{
31+
return typeface;
32+
}
33+
34+
if(key.Style != FontStyle.Normal)
35+
{
36+
key = new Typeface(key.FontFamily, FontStyle.Normal, key.Weight);
37+
}
38+
39+
if(TryFindWeightFallback(key, out typeface))
40+
{
41+
return typeface;
42+
}
43+
44+
//Nothing was found so we try some regular typeface.
45+
if (_typefaces.TryGetValue(new Typeface(key.FontFamily), out typeface))
46+
{
47+
return typeface;
48+
}
3249

50+
SKTypeface skTypeface = null;
51+
52+
foreach(var pair in _typefaces)
53+
{
54+
skTypeface = pair.Value;
55+
56+
if (skTypeface.FamilyName.Contains(key.FontFamily.Name))
57+
{
58+
return skTypeface;
59+
}
60+
}
61+
62+
return skTypeface;
63+
}
64+
65+
private bool TryFindWeightFallback(Typeface key, out SKTypeface typeface)
66+
{
67+
typeface = null;
3368
var weight = (int)key.Weight;
3469

35-
weight -= weight % 50; // make sure we start at a full weight
70+
//If the target weight given is between 400 and 500 inclusive
71+
if (weight >= 400 && weight <= 500)
72+
{
73+
//Look for available weights between the target and 500, in ascending order.
74+
for (var i = 0; weight + i <= 500; i += 50)
75+
{
76+
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight + i)), out typeface))
77+
{
78+
return true;
79+
}
80+
}
3681

37-
for (var i = 0; i < 2; i++)
82+
//If no match is found, look for available weights less than the target, in descending order.
83+
for (var i = 0; weight - i >= 100; i += 50)
84+
{
85+
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight - i)), out typeface))
86+
{
87+
return true;
88+
}
89+
}
90+
91+
//If no match is found, look for available weights greater than 500, in ascending order.
92+
for (var i = 0; weight + i <= 900; i += 50)
93+
{
94+
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight + i)), out typeface))
95+
{
96+
return true;
97+
}
98+
}
99+
}
100+
101+
//If a weight less than 400 is given, look for available weights less than the target, in descending order.
102+
if (weight < 400)
38103
{
39-
for (var j = 0; j < initialWeight; j += 50)
104+
for (var i = 0; weight - i >= 100; i += 50)
105+
{
106+
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight - i)), out typeface))
107+
{
108+
return true;
109+
}
110+
}
111+
112+
//If no match is found, look for available weights less than the target, in descending order.
113+
for (var i = 0; weight + i <= 900; i += 50)
40114
{
41-
if (weight - j >= 100)
115+
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight + i)), out typeface))
42116
{
43-
if (typefaces.TryGetValue(new Typeface(key.FontFamily, (FontStyle)i, (FontWeight)(weight - j)), out typeface))
44-
{
45-
return typeface;
46-
}
117+
return true;
47118
}
119+
}
120+
}
48121

49-
if (weight + j > 900)
122+
//If a weight greater than 500 is given, look for available weights greater than the target, in ascending order.
123+
if (weight > 500)
124+
{
125+
for (var i = 0; weight + i <= 900; i += 50)
126+
{
127+
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight + i)), out typeface))
50128
{
51-
continue;
129+
return true;
52130
}
131+
}
53132

54-
if (typefaces.TryGetValue(new Typeface(key.FontFamily, (FontStyle)i, (FontWeight)(weight + j)), out typeface))
133+
//If no match is found, look for available weights less than the target, in descending order.
134+
for (var i = 0; weight - i >= 100; i += 50)
135+
{
136+
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight - i)), out typeface))
55137
{
56-
return typeface;
138+
return true;
57139
}
58140
}
59141
}
60142

61-
//Nothing was found so we try to get a regular typeface.
62-
return typefaces.TryGetValue(new Typeface(key.FontFamily), out typeface) ? typeface : null;
143+
return false;
63144
}
64145
}
65146
}

src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFa
5151
if (typeface == null)
5252
throw new InvalidOperationException("Typeface could not be loaded.");
5353

54-
if (typeface.FamilyName != fontFamily.Name)
54+
if (!typeface.FamilyName.Contains(fontFamily.Name))
5555
{
5656
continue;
5757
}

0 commit comments

Comments
 (0)