Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/stable/0.10.x' into fixes/nullab…
Browse files Browse the repository at this point in the history
…le-avalonia-native
  • Loading branch information
danwalmsley committed Apr 22, 2022
2 parents d06464d + 4a90d96 commit fa86e9b
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 49 deletions.
24 changes: 24 additions & 0 deletions Avalonia.sln
Original file line number Diff line number Diff line change
Expand Up @@ -2003,6 +2003,30 @@ Global
{909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhone.Build.0 = Release|Any CPU
{909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhone.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhone.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|Any CPU.Build.0 = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhone.ActiveCfg = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhone.Build.0 = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
Expand Down
57 changes: 39 additions & 18 deletions src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using System;
using System.Globalization;
using System.Linq;
using Avalonia.Controls.Presenters;
using Avalonia.Input;
using Avalonia.Input.GestureRecognizers;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.VisualTree;

namespace Avalonia.Controls.Primitives
Expand Down Expand Up @@ -58,18 +62,18 @@ public class DateTimePickerPanel : Panel, ILogicalScrollable
private Vector _offset;
private bool _hasInit;
private bool _suppressUpdateOffset;
private ListBoxItem _pressedItem;
private ScrollContentPresenter? _parentScroller;

public DateTimePickerPanel()
{
FormatDate = DateTime.Now;
AddHandler(ListBoxItem.PointerPressedEvent, OnItemPointerDown, Avalonia.Interactivity.RoutingStrategies.Bubble);
AddHandler(ListBoxItem.PointerReleasedEvent, OnItemPointerUp, Avalonia.Interactivity.RoutingStrategies.Bubble);
AddHandler(TappedEvent, OnItemTapped, RoutingStrategies.Bubble);
}

static DateTimePickerPanel()
{
FocusableProperty.OverrideDefaultValue<DateTimePickerPanel>(true);
BackgroundProperty.OverrideDefaultValue<DateTimePickerPanel>(Brushes.Transparent);
AffectsMeasure<DateTimePickerPanel>(ItemHeightProperty);
}

Expand Down Expand Up @@ -254,6 +258,8 @@ public Vector Offset
_suppressUpdateOffset = true;
SelectedValue = (int)newSel * Increment + MinimumValue;
_suppressUpdateOffset = false;

System.Diagnostics.Debug.WriteLine($"Offset: {_offset} ItemHeight: {ItemHeight}");
}
}

Expand All @@ -269,7 +275,7 @@ public Vector Offset

public Size Extent => _extent;

public Size Viewport => new Size(0, ItemHeight);
public Size Viewport => Bounds.Size;

public event EventHandler ScrollInvalidated;

Expand Down Expand Up @@ -340,6 +346,20 @@ protected override Size ArrangeOverride(Size finalSize)
return finalSize;
}

protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
_parentScroller = this.GetVisualParent() as ScrollContentPresenter;
_parentScroller?.AddHandler(Gestures.ScrollGestureEndedEvent, OnScrollGestureEnded);
}

protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromVisualTree(e);
_parentScroller?.RemoveHandler(Gestures.ScrollGestureEndedEvent, OnScrollGestureEnded);
_parentScroller = null;
}

protected override void OnKeyDown(KeyEventArgs e)
{
switch (e.Key)
Expand Down Expand Up @@ -523,22 +543,13 @@ private int CoerceSelected(int newValue)
return newValue;
}

private void OnItemPointerDown(object sender, PointerPressedEventArgs e)
private void OnItemTapped(object sender, TappedEventArgs e)
{
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
if (e.Source is IVisual source &&
GetItemFromSource(source) is ListBoxItem listBoxItem &&
listBoxItem.Tag is int tag)
{
_pressedItem = GetItemFromSource((IVisual)e.Source);
e.Handled = true;
}
}

private void OnItemPointerUp(object sender, PointerReleasedEventArgs e)
{
if (e.GetCurrentPoint(this).Properties.PointerUpdateKind == PointerUpdateKind.LeftButtonReleased &&
_pressedItem != null)
{
SelectedValue = (int)GetItemFromSource((IVisual)e.Source).Tag;
_pressedItem = null;
SelectedValue = tag;
e.Handled = true;
}
}
Expand All @@ -562,5 +573,15 @@ public void RaiseScrollInvalidated(EventArgs e)
{
ScrollInvalidated?.Invoke(this, e);
}

private void OnScrollGestureEnded(object? sender, ScrollGestureEndedEventArgs e)
{
var snapY = Math.Round(Offset.Y / ItemHeight) * ItemHeight;

if (snapY != Offset.Y)
{
Offset = Offset.WithY(snapY);
}
}
}
}
4 changes: 2 additions & 2 deletions src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ private void OnScrollGesture(object sender, ScrollGestureEventArgs e)
{
var logicalUnits = delta.Y / logicalScrollItemSize.Y;
delta = delta.WithY(delta.Y - logicalUnits * logicalScrollItemSize.Y);
dy = logicalUnits * scrollable!.ScrollSize.Height;
dy = logicalUnits;
}
else
dy = delta.Y;
Expand All @@ -389,7 +389,7 @@ private void OnScrollGesture(object sender, ScrollGestureEventArgs e)
{
var logicalUnits = delta.X / logicalScrollItemSize.X;
delta = delta.WithX(delta.X - logicalUnits * logicalScrollItemSize.X);
dx = logicalUnits * scrollable!.ScrollSize.Width;
dx = logicalUnits;
}
else
dx = delta.X;
Expand Down
21 changes: 14 additions & 7 deletions src/Skia/Avalonia.Skia/FontManagerImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ public IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = fa
[ThreadStatic] private static string[] t_languageTagBuffer;

public bool TryMatchCharacter(int codepoint, FontStyle fontStyle,
FontWeight fontWeight,
FontFamily fontFamily, CultureInfo culture, out Typeface fontKey)
FontWeight fontWeight, FontFamily fontFamily, CultureInfo culture, out Typeface fontKey)
{
SKFontStyle skFontStyle;

Expand Down Expand Up @@ -109,23 +108,31 @@ public IGlyphTypefaceImpl CreateGlyphTypeface(Typeface typeface)
if (typeface.FontFamily.Key == null)
{
var defaultName = SKTypeface.Default.FamilyName;
var fontStyle = new SKFontStyle((SKFontStyleWeight)typeface.Weight, SKFontStyleWidth.Normal, (SKFontStyleSlant)typeface.Style);

var fontStyle = new SKFontStyle((SKFontStyleWeight)typeface.Weight, SKFontStyleWidth.Normal,
(SKFontStyleSlant)typeface.Style);

foreach (var familyName in typeface.FontFamily.FamilyNames)
{
if(familyName == FontFamily.DefaultFontFamilyName)
{
continue;
}

skTypeface = _skFontManager.MatchFamily(familyName, fontStyle);

if (skTypeface is null
|| (!skTypeface.FamilyName.Equals(familyName, StringComparison.Ordinal)
&& defaultName.Equals(skTypeface.FamilyName, StringComparison.Ordinal)))
if (skTypeface is null || defaultName.Equals(skTypeface.FamilyName, StringComparison.Ordinal))
{
continue;
}

break;
}

skTypeface ??= _skFontManager.MatchTypeface(SKTypeface.Default, fontStyle);
// MatchTypeface can return "null" if matched typeface wasn't found for the style
// Fallback to the default typeface and styles instead.
skTypeface ??= _skFontManager.MatchTypeface(SKTypeface.Default, fontStyle)
?? SKTypeface.Default;
}
else
{
Expand Down
123 changes: 102 additions & 21 deletions src/Skia/Avalonia.Skia/SKTypefaceCollection.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Media;
using SkiaSharp;

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

public SKTypeface Get(Typeface typeface)
{
return GetNearestMatch(_typefaces, typeface);
return GetNearestMatch(typeface);
}

private static SKTypeface GetNearestMatch(IDictionary<Typeface, SKTypeface> typefaces, Typeface key)
private SKTypeface GetNearestMatch(Typeface key)
{
if (typefaces.TryGetValue(key, out var typeface))
if (_typefaces.Count == 0)
{
return typeface;
return null;
}

var initialWeight = (int)key.Weight;
if (_typefaces.TryGetValue(key, out var typeface))
{
return typeface;
}

if(key.Style != FontStyle.Normal)
{
key = new Typeface(key.FontFamily, FontStyle.Normal, key.Weight);
}

if(TryFindWeightFallback(key, out typeface))
{
return typeface;
}

//Nothing was found so we try some regular typeface.
if (_typefaces.TryGetValue(new Typeface(key.FontFamily), out typeface))
{
return typeface;
}

SKTypeface skTypeface = null;

foreach(var pair in _typefaces)
{
skTypeface = pair.Value;

if (skTypeface.FamilyName.Contains(key.FontFamily.Name))
{
return skTypeface;
}
}

return skTypeface;
}

private bool TryFindWeightFallback(Typeface key, out SKTypeface typeface)
{
typeface = null;
var weight = (int)key.Weight;

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

for (var i = 0; i < 2; i++)
//If no match is found, look for available weights less than the target, in descending order.
for (var i = 0; weight - i >= 100; i += 50)
{
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight - i)), out typeface))
{
return true;
}
}

//If no match is found, look for available weights greater than 500, in ascending order.
for (var i = 0; weight + i <= 900; i += 50)
{
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight + i)), out typeface))
{
return true;
}
}
}

//If a weight less than 400 is given, look for available weights less than the target, in descending order.
if (weight < 400)
{
for (var j = 0; j < initialWeight; j += 50)
for (var i = 0; weight - i >= 100; i += 50)
{
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight - i)), out typeface))
{
return true;
}
}

//If no match is found, look for available weights less than the target, in descending order.
for (var i = 0; weight + i <= 900; i += 50)
{
if (weight - j >= 100)
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight + i)), out typeface))
{
if (typefaces.TryGetValue(new Typeface(key.FontFamily, (FontStyle)i, (FontWeight)(weight - j)), out typeface))
{
return typeface;
}
return true;
}
}
}

if (weight + j > 900)
//If a weight greater than 500 is given, look for available weights greater than the target, in ascending order.
if (weight > 500)
{
for (var i = 0; weight + i <= 900; i += 50)
{
if (_typefaces.TryGetValue(new Typeface(key.FontFamily, key.Style, (FontWeight)(weight + i)), out typeface))
{
continue;
return true;
}
}

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

//Nothing was found so we try to get a regular typeface.
return typefaces.TryGetValue(new Typeface(key.FontFamily), out typeface) ? typeface : null;
return false;
}
}
}
2 changes: 1 addition & 1 deletion src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFa
if (typeface == null)
throw new InvalidOperationException("Typeface could not be loaded.");

if (typeface.FamilyName != fontFamily.Name)
if (!typeface.FamilyName.Contains(fontFamily.Name))
{
continue;
}
Expand Down

0 comments on commit fa86e9b

Please sign in to comment.