Skip to content

Commit

Permalink
refactor(Studio): Migrate subpixel-indicator to Skia
Browse files Browse the repository at this point in the history
  • Loading branch information
psyGamer committed Oct 27, 2024
1 parent fd77d45 commit 526fccd
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 16 deletions.
29 changes: 19 additions & 10 deletions Studio/CelesteStudio/Editing/GameInfoPanel.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
using System;
using System.Text;
using CelesteStudio.Communication;
using CelesteStudio.Controls;
using CelesteStudio.Data;
using CelesteStudio.Util;
using Eto.Drawing;
using Eto.Forms;
using SkiaSharp;
using StudioCommunication.Util;
using System.ComponentModel;

namespace CelesteStudio.Editing;

public sealed class GameInfo : Panel {
private sealed class SubpixelIndicator : Drawable {
protected override void OnPaint(PaintEventArgs e) {
private sealed class SubpixelIndicator : SkiaDrawable {
protected override void Draw(PaintEventArgs e, SKSurface surface, SKImageInfo imageInfo) {
surface.Canvas.Clear();

var remainder = CommunicationWrapper.PlayerPositionRemainder;

float subpixelLeft = (float)Math.Round(remainder.X + 0.5f, CommunicationWrapper.GameSettings.SubpixelIndicatorDecimals, MidpointRounding.AwayFromZero);
float subpixelTop = (float)Math.Round(remainder.Y + 0.5f, CommunicationWrapper.GameSettings.SubpixelIndicatorDecimals, MidpointRounding.AwayFromZero);
float subpixelRight = 1.0f - subpixelLeft;
float subpixelBottom = 1.0f - subpixelTop;

var font = FontManager.StatusFont;
var font = FontManager.SKStatusFont;

const float indicatorPadding = 8.0f;
const float rectPadding = 5.0f;
Expand All @@ -44,18 +49,22 @@ protected override void OnPaint(PaintEventArgs e) {
string top = subpixelTop.ToFormattedString(vDecimals);
string bottom = subpixelBottom.ToFormattedString(vDecimals);

e.Graphics.DrawText(font, Settings.Instance.Theme.StatusFg, x - rectPadding - font.MeasureWidth(left), y + (rectSize - textHeight) / 2.0f, left);
e.Graphics.DrawText(font, Settings.Instance.Theme.StatusFg, x + rectPadding + rectSize, y + (rectSize - textHeight) / 2.0f, right);
surface.Canvas.DrawText(left, x - rectPadding - font.MeasureWidth(left), y + (rectSize - textHeight) / 2.0f + font.Offset(), font, Settings.Instance.Theme.StatusFgPaint);
surface.Canvas.DrawText(right, x + rectPadding + rectSize, y + (rectSize - textHeight) / 2.0f + font.Offset(), font, Settings.Instance.Theme.StatusFgPaint);

e.Graphics.DrawText(font, Settings.Instance.Theme.StatusFg, x + (rectSize - font.MeasureWidth(top)) / 2.0f, y - rectPadding - textHeight, top);
e.Graphics.DrawText(font, Settings.Instance.Theme.StatusFg, x + (rectSize - font.MeasureWidth(bottom)) / 2.0f, y + rectPadding + rectSize, bottom);
surface.Canvas.DrawText(top, MathF.Round(x + (rectSize - font.MeasureWidth(top)) / 2.0f), MathF.Round(y - rectPadding - textHeight + font.Offset()), font, Settings.Instance.Theme.StatusFgPaint);
surface.Canvas.DrawText(bottom, x + (rectSize - font.MeasureWidth(bottom)) / 2.0f, y + rectPadding + rectSize + font.Offset(), font, Settings.Instance.Theme.StatusFgPaint);

int boxThickness = Math.Max(1, (int)Math.Round(rectSize / 20.0f));
float dotThickness = boxThickness * 1.25f;
using var boxPen = new Pen(Settings.Instance.Theme.SubpixelIndicatorBox, boxThickness);

e.Graphics.DrawRectangle(boxPen, x, y, rectSize, rectSize);
e.Graphics.FillRectangle(Settings.Instance.Theme.SubpixelIndicatorDot, x + (rectSize - dotThickness) * subpixelLeft, y + (rectSize - dotThickness) * subpixelTop, dotThickness, dotThickness);
using var boxPaint = new SKPaint();
boxPaint.ColorF = Settings.Instance.Theme.SubpixelIndicatorBox.ToSkia();
boxPaint.Style = SKPaintStyle.Stroke;
boxPaint.StrokeWidth = boxThickness;

surface.Canvas.DrawRect(x, y, rectSize, rectSize, boxPaint);
surface.Canvas.DrawRect(x + (rectSize - dotThickness) * subpixelLeft, y + (rectSize - dotThickness) * subpixelTop, dotThickness, dotThickness, Settings.Instance.Theme.SubpixelIndicatorDotPaint);

Width = (int)((textWidth + rectPadding + indicatorPadding) * 2.0f + rectSize);
Height = (int)((textHeight + rectPadding + indicatorPadding) * 2.0f + rectSize);
Expand Down
10 changes: 8 additions & 2 deletions Studio/CelesteStudio/Editing/Theme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public struct Theme {

// Cache SKPaints
private StylePaint? _actionPaint, _anglePaint, _breakpointPaint, _savestateBreakpointPaint, _delimiter, _command, _frame, _comment;
private SKPaint? _commentBox, _popupMenuFgPaint, _popupMenuFgDisabledPaint, _popupMenuFgExtraPaint, _popupMenuBgPaint, _popupMenuSelectedPaint;
private SKPaint? _commentBox, _statusFgPaint, _subpixelIndicatorDotPaint, _popupMenuFgPaint, _popupMenuFgDisabledPaint, _popupMenuFgExtraPaint, _popupMenuBgPaint, _popupMenuSelectedPaint;

public StylePaint ActionPaint => _actionPaint ??= Action.CreatePaint();
public StylePaint AnglePaint => _anglePaint ??= Angle.CreatePaint();
Expand All @@ -83,6 +83,9 @@ public struct Theme {
public StylePaint FramePaint => _frame ??= Frame.CreatePaint();
public StylePaint CommentPaint => _comment ??= Comment.CreatePaint();
public SKPaint CommentBoxPaint => _commentBox ??= Comment.CreateForegroundPaint(SKPaintStyle.Stroke);

public SKPaint StatusFgPaint => _statusFgPaint ??= new SKPaint { ColorF = StatusFg.ToSkia(), Style = SKPaintStyle.Fill, IsAntialias = true };
public SKPaint SubpixelIndicatorDotPaint => _subpixelIndicatorDotPaint ??= new SKPaint { ColorF = SubpixelIndicatorDot.ToSkia(), Style = SKPaintStyle.Fill, IsAntialias = true };
public SKPaint PopupMenuFgPaint => _popupMenuFgPaint ??= new SKPaint { ColorF = PopupMenuFg.ToSkia(), Style = SKPaintStyle.Fill, IsAntialias = true };
public SKPaint PopupMenuFgDisabledPaint => _popupMenuFgDisabledPaint ??= new SKPaint { ColorF = PopupMenuFgDisabled.ToSkia(), Style = SKPaintStyle.Fill, IsAntialias = true };
public SKPaint PopupMenuFgExtraPaint => _popupMenuFgExtraPaint ??= new SKPaint { ColorF = PopupMenuFgExtra.ToSkia(), Style = SKPaintStyle.Fill, IsAntialias = true };
Expand All @@ -99,14 +102,17 @@ public void InvalidateCache() {
_frame?.Dispose();
_comment?.Dispose();
_commentBox?.Dispose();

_statusFgPaint?.Dispose();
_subpixelIndicatorDotPaint?.Dispose();
_popupMenuFgPaint?.Dispose();
_popupMenuFgDisabledPaint?.Dispose();
_popupMenuFgExtraPaint?.Dispose();
_popupMenuBgPaint?.Dispose();
_popupMenuSelectedPaint?.Dispose();

_actionPaint = _anglePaint = _breakpointPaint = _savestateBreakpointPaint = _delimiter = _command = _frame = _comment = null;
_commentBox = _popupMenuFgPaint = _popupMenuFgDisabledPaint = _popupMenuFgExtraPaint = _popupMenuBgPaint = _popupMenuSelectedPaint = null;
_commentBox = _statusFgPaint = _subpixelIndicatorDotPaint = _popupMenuFgPaint = _popupMenuFgDisabledPaint = _popupMenuFgExtraPaint = _popupMenuBgPaint = _popupMenuSelectedPaint = null;
}

public bool DarkMode;
Expand Down
10 changes: 6 additions & 4 deletions Studio/CelesteStudio/FontManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static class FontManager {
#endif

private static Font? editorFontRegular, editorFontBold, editorFontItalic, editorFontBoldItalic, statusFont;
private static SKFont? skEditorFontRegular, skEditorFontBold, skEditorFontItalic, skEditorFontBoldItalic, skPopupFont;
private static SKFont? skEditorFontRegular, skEditorFontBold, skEditorFontItalic, skEditorFontBoldItalic, skStatusFont, skPopupFont;

public static Font EditorFontRegular => editorFontRegular ??= CreateEditor(FontStyle.None);
public static Font EditorFontBold => editorFontBold ??= CreateEditor(FontStyle.Bold);
Expand All @@ -30,6 +30,7 @@ public static class FontManager {
public static SKFont SKEditorFontBold => skEditorFontBold ??= CreateSKFont(Settings.Instance.FontFamily, Settings.Instance.EditorFontSize * Settings.Instance.FontZoom, FontStyle.Bold);
public static SKFont SKEditorFontItalic => skEditorFontItalic ??= CreateSKFont(Settings.Instance.FontFamily, Settings.Instance.EditorFontSize * Settings.Instance.FontZoom, FontStyle.Italic);
public static SKFont SKEditorFontBoldItalic => skEditorFontBoldItalic ??= CreateSKFont(Settings.Instance.FontFamily, Settings.Instance.EditorFontSize * Settings.Instance.FontZoom, FontStyle.Bold | FontStyle.Italic);
public static SKFont SKStatusFont => skStatusFont ??= CreateSKFont(Settings.Instance.FontFamily, Settings.Instance.StatusFontSize);
public static SKFont SKPopupFont => skPopupFont ??= CreateSKFont(Settings.Instance.FontFamily, Settings.Instance.PopupFontSize);

private static FontFamily? builtinFontFamily;
Expand Down Expand Up @@ -70,7 +71,7 @@ public static SKFont CreateSKFont(string fontFamily, float size, FontStyle style
});
var typeface = SKTypeface.FromStream(stream);

return new SKFont(typeface, size * dpi) { LinearMetrics = true };
return new SKFont(typeface, size * dpi) { LinearMetrics = true, Subpixel = true, Edging = SKFontEdging.SubpixelAntialias };
} else {
var typeface = style switch {
FontStyle.None => SKTypeface.FromFamilyName(fontFamily, SKFontStyleWeight.Light, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright),
Expand All @@ -80,7 +81,7 @@ public static SKFont CreateSKFont(string fontFamily, float size, FontStyle style
_ => throw new UnreachableException(),
};

return new SKFont(typeface, size * dpi) { LinearMetrics = true };
return new SKFont(typeface, size * dpi) { LinearMetrics = true, Subpixel = true, Edging = SKFontEdging.SubpixelAntialias };
}
}

Expand Down Expand Up @@ -147,9 +148,10 @@ public static void OnFontChanged() {
skEditorFontBold?.Dispose();
skEditorFontItalic?.Dispose();
skEditorFontBoldItalic?.Dispose();
skStatusFont?.Dispose();
skPopupFont?.Dispose();

skEditorFontRegular = skEditorFontBold = skEditorFontItalic = skEditorFontBoldItalic = skPopupFont = null;
skEditorFontRegular = skEditorFontBold = skEditorFontItalic = skEditorFontBoldItalic = skStatusFont = skPopupFont = null;
}

private static Font CreateEditor(FontStyle style) => CreateFont(Settings.Instance.FontFamily, Settings.Instance.EditorFontSize * Settings.Instance.FontZoom, style);
Expand Down

0 comments on commit 526fccd

Please sign in to comment.