Skip to content

Commit

Permalink
要素のテキストの色を修正
Browse files Browse the repository at this point in the history
  • Loading branch information
yuto-trd committed Aug 28, 2023
1 parent ef8f80f commit dff60d2
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/Beutl.Utilities/MathUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public static class MathUtilities
// smallest such that 1.0+DoubleEpsilon != 1.0
internal static readonly double s_doubleEpsilon = 2.2204460492503131e-016;

private const float FloatEpsilon = 1.192092896e-07F;
public const float FloatEpsilon = 1.192092896e-07F;

public static float ToRadians(float degrees)
{
Expand Down
69 changes: 54 additions & 15 deletions src/Beutl/ViewModels/ElementViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json.Nodes;
using System.Numerics;
using System.Text.Json.Nodes;

using Avalonia;
using Avalonia.Input;
Expand All @@ -7,20 +8,17 @@
using Beutl.Commands;
using Beutl.Models;
using Beutl.ProjectSystem;
using Beutl.Utilities;

using Reactive.Bindings;
using Reactive.Bindings.Extensions;

using HslColor = Avalonia.Media.HslColor;

namespace Beutl.ViewModels;

public sealed class ElementViewModel : IDisposable
{
private static readonly Graphics.ColorMatrix s_grayscale = new(
0.21f, 0.72f, 0.07f, 0, 0,
0.21f, 0.72f, 0.07f, 0, 0,
0.21f, 0.72f, 0.07f, 0, 0,
0.000f, 0.000f, 0.000f, 1, 0);
private static readonly Graphics.ColorMatrix s_contrast100 = Graphics.ColorMatrix.CreateContrast(100);
private readonly CompositeDisposable _disposables = new();
private IClipboard? _clipboard;

Expand Down Expand Up @@ -67,14 +65,7 @@ public ElementViewModel(Element element, TimelineViewModel timeline)
.ToReactiveProperty()
.AddTo(_disposables);

TextColor = Color.Select(c =>
{
//filter: invert(100 %) grayscale(100 %) contrast(100);
var cc = new Media.Color(c.A, (byte)(255 - c.R), (byte)(255 - c.G), (byte)(255 - c.B));
cc = s_grayscale * cc;
cc = s_contrast100 * cc;
return cc.ToAvalonia();
})
TextColor = Color.Select(GetTextColor)
.ToReadOnlyReactivePropertySlim()
.AddTo(_disposables);

Expand Down Expand Up @@ -342,6 +333,54 @@ private void OnSplit(TimeSpan timeSpan)
Scene.AddChild(backwardLayer).DoAndRecord(CommandRecorder.Default);
}

// https://github.com/google/skia/blob/0d39172f35d259b6ab888974177bc4e6d839d44c/src/effects/SkHighContrastFilter.cpp
private Avalonia.Media.Color GetTextColor(Avalonia.Media.Color color)
{
static Vector3 Mix(Vector3 x, Vector3 y, float a)
{
return (x * (1 - a)) + (y * a);
}

static Vector3 Saturate(Vector3 a)
{
return Vector3.Clamp(a, new(0), new(1));
}

static Avalonia.Media.Color ToColor(Vector3 vector)
{
return new(255, (byte)(vector.X * 255), (byte)(vector.Y * 255), (byte)(vector.Z * 255));
}

static Vector3 ToVector3(Avalonia.Media.Color color)
{
return new Vector3(color.R / 255f, color.G / 255f, color.B / 255f);
}

// 計算機イプシロン
// 'float.Epsilon'は使わないで
const float Epsilon = MathUtilities.FloatEpsilon;
float contrast = 1.0f;
contrast = Math.Max(-1.0f + Epsilon, Math.Min(contrast, +1.0f - Epsilon));

contrast = (1.0f + contrast) / (1.0f - contrast);

Vector3 c = ToVector3(color);
float grayscale = Vector3.Dot(new(0.2126f, 0.7152f, 0.0722f), c);
c = new Vector3(grayscale);

// brightness
//c = Vector3.One - c;

//lightness
HslColor hsl = ToColor(c).ToHsl();
c = ToVector3(HslColor.ToRgb(hsl.H, hsl.S, 1 - hsl.L, hsl.A));

c = Mix(new Vector3(0.5f), c, contrast);
c = Saturate(c);

return ToColor(c);
}

public record struct PrepareAnimationContext(
Thickness Margin,
Thickness BorderMargin,
Expand Down

0 comments on commit dff60d2

Please sign in to comment.