Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A lot of font editor improvements. #1328

Merged
merged 23 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
70403f9
A little layout change of the font editor.
VladiStep Apr 12, 2023
35d49f6
Fix #1319, close #124.
VladiStep Apr 13, 2023
23a0625
Make the tileset editor image cursor "hand", add a hint for it.
VladiStep Apr 13, 2023
092673d
Make the font texture clickable.
VladiStep Apr 13, 2023
db3e368
The "Glyphs" table shows actual characters (and their codes on hover).
VladiStep Apr 13, 2023
3b3b85c
Add the "Edit selected glyph rectangle" button; move font editor file…
VladiStep Apr 13, 2023
b3851f9
Add new "EditGlyphRectangleWindow", add `DisplayBorder` property for …
VladiStep Apr 14, 2023
a5db326
Make "EditGlyphRectangleWindow" functional; add `Clone()` for font an…
VladiStep Apr 15, 2023
2f69804
Add a character hint for the rectangles; limit rectangle size operati…
VladiStep Apr 15, 2023
ec380c8
Add an option to select a region for an empty glyph; improve the "Edi…
VladiStep Apr 15, 2023
be61249
Add the "Update range" button for the font; add a success message for…
VladiStep Apr 15, 2023
ba8ebe8
Add the missing documentation for font and glyph.
VladiStep Apr 16, 2023
04ffb40
Add missing font editor fields, add `IsVersionAtLeastConverter`.
VladiStep Apr 16, 2023
abda268
Use `IsVersionAtLeastConverter` instead of proprietary ones.
VladiStep Apr 16, 2023
1d25c09
Fix `GlyphKerning.Character` documentation.
VladiStep Apr 16, 2023
aced968
Close #1181, fix #1325.
VladiStep Apr 16, 2023
0c8ba69
Make the tileset texture hints work only in GMS 2+.
VladiStep Apr 16, 2023
b8e3f58
Add a blinking preview for the shift and offset.
VladiStep Apr 17, 2023
d1263e7
Handle errors in the glyph rectangle editor window.
VladiStep Apr 17, 2023
6c6734b
Fix the updated hints for the two rows.
VladiStep Apr 17, 2023
f91b5a3
Make glyph shift update on edit.
VladiStep Apr 17, 2023
fa6588c
Fixed a crash on empty glyphs list, reverted the row gap (size increa…
VladiStep Apr 17, 2023
3af6552
Make the new font scale 1, add an error message for the empty texture.
VladiStep Apr 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 56 additions & 15 deletions UndertaleModLib/Models/UndertaleFont.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,28 @@ public class UndertaleFont : UndertaleNamedResource, IDisposable
/// <summary>
/// The x scale this font uses.
/// </summary>
public float ScaleX { get; set; }
public float ScaleX { get; set; } = 1;

/// <summary>
/// The y scale this font uses.
/// </summary>
public float ScaleY { get; set; }
public float ScaleY { get; set; } = 1;

/// <summary>
/// TODO: currently unknown, needs investigation. GM 2022.2 specific?
/// TODO: currently unknown, needs investigation.
/// Probably this - <see href="https://en.wikipedia.org/wiki/Ascender_(typography)"/>
/// </summary>
/// <remarks>
/// Was introduced in GM 2022.2.
/// </remarks>
public uint Ascender { get; set; }

/// <summary>
/// A spread value that's used for SDF rendering.
/// Introduced in GM 2023.2.
/// </summary>
/// <remarks>
/// Was introduced in GM 2023.2.
/// </remarks>
/// <value><c>0</c> if SDF is disabled for this font.</value>
public uint SDFSpread { get; set; }

Expand All @@ -92,8 +98,11 @@ public class UndertaleFont : UndertaleNamedResource, IDisposable
public UndertalePointerList<Glyph> Glyphs { get; private set; } = new UndertalePointerList<Glyph>();

/// <summary>
/// TODO: currently unknown, needs investigation. Exists since bytecode 17, but seems to be only get checked since 2022.2+.
/// The maximum offset from the baseline to the top of the font
/// </summary>
/// <remarks>
/// Exists since bytecode 17, but seems to be only get checked in GM 2022.2+.
/// </remarks>
public int AscenderOffset { get; set; }


Expand Down Expand Up @@ -130,12 +139,12 @@ public class Glyph : UndertaleObject, IDisposable


/// <summary>
/// TODO: something kerning related
/// The number of pixels to shift right when advancing to the next character.
/// </summary>
public short Shift { get; set; }

/// <summary>
/// TODO: something kerning related.
/// The number of pixels to horizontally offset the rendering of this glyph.
/// </summary>
public short Offset { get; set; }

Expand Down Expand Up @@ -187,28 +196,60 @@ public class GlyphKerning : UndertaleObject, IStaticChildObjectsSize
public static readonly uint ChildObjectsSize = 4;

/// <summary>
/// TODO: unknown?
/// The code point of the preceeding character.
/// </summary>
public short Other;
public short Character { get; set; }

/// <summary>
/// TODO: unknown?
/// An amount of pixels to add to the existing <see cref="Shift"/>.
/// </summary>
public short Amount;
public short ShiftModifier { get; set; }

/// <inheritdoc />
public void Serialize(UndertaleWriter writer)
{
writer.Write(Other);
writer.Write(Amount);
writer.Write(Character);
writer.Write(ShiftModifier);
}

/// <inheritdoc />
public void Unserialize(UndertaleReader reader)
{
Other = reader.ReadInt16();
Amount = reader.ReadInt16();
Character = reader.ReadInt16();
ShiftModifier = reader.ReadInt16();
}

/// <summary>
/// Makes a copy of this <see cref="GlyphKerning"/>.
/// </summary>
/// <returns>The copy.</returns>
public GlyphKerning Clone()
{
return new GlyphKerning() { ShiftModifier = this.ShiftModifier, Character = this.Character };
}
}

/// <summary>
/// Makes a copy of this <see cref="Glyph"/>.
/// </summary>
/// <returns>The copy.</returns>
public Glyph Clone()
{
var kerning = new UndertaleSimpleListShort<GlyphKerning>();
foreach (var kern in Kerning)
kerning.InternalAdd(kern.Clone());

return new Glyph()
{
Character = this.Character,
SourceX = this.SourceX,
SourceY = this.SourceY,
SourceWidth = this.SourceWidth,
SourceHeight = this.SourceHeight,
Shift = this.Shift,
Offset = this.Offset,
Kerning = kerning
};
}

/// <inheritdoc/>
Expand Down
39 changes: 37 additions & 2 deletions UndertaleModTool/Controls/System/DataGridDark.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
using System.Windows;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Threading;

namespace UndertaleModTool
{
/// <summary>
/// A standard data grid which compatible with the dark mode.
/// </summary>
public partial class DataGridDark : System.Windows.Controls.DataGrid
public partial class DataGridDark : DataGrid
{
/// <summary>Initializes a new instance of the data grid.</summary>
public DataGridDark()
{
Loaded += DataGrid_Loaded;
AddingNewItem += DataGrid_AddingNewItem;
}

private void DataGrid_AddingNewItem(object sender, AddingNewItemEventArgs e)
{
_ = Task.Run(() =>
{
Dispatcher.Invoke(() =>
{
UpdateLayout();
CommitEdit(DataGridEditingUnit.Row, true);
});
});
}

private void DataGrid_Loaded(object sender, RoutedEventArgs e)
Expand All @@ -22,5 +38,24 @@ private void DataGrid_Loaded(object sender, RoutedEventArgs e)

pres.SetResourceReference(ForegroundProperty, "CustomTextBrush");
}

protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
if (e.Property == VisibilityProperty)
{
if ((Visibility)e.NewValue == Visibility.Visible)
{
base.OnPropertyChanged(e);
UpdateLayout();

var pres = MainWindow.FindVisualChild<DataGridColumnHeadersPresenter>(this);
pres?.SetResourceReference(ForegroundProperty, "CustomTextBrush");

return;
}
}

base.OnPropertyChanged(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
<UserControl.Resources>
<local:UndertaleCachedImageLoader x:Key="UndertaleCachedImageLoader"/>
</UserControl.Resources>
<Canvas Width="{Binding BoundingWidth, Mode=OneWay}" Height="{Binding BoundingHeight, Mode=OneWay}" SnapsToDevicePixels="True">
<Canvas Width="{Binding BoundingWidth, Mode=OneWay}" Height="{Binding BoundingHeight, Mode=OneWay}"
SnapsToDevicePixels="True">
<Border Canvas.Left="{Binding TargetX, Mode=OneWay}" Canvas.Top="{Binding TargetY, Mode=OneWay}"
Width="{Binding TargetWidth, Mode=OneWay}" Height="{Binding TargetHeight, Mode=OneWay}"
BorderBrush="DarkCyan" BorderThickness="1" Name="RenderAreaBorder" SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="NearestNeighbor">
BorderBrush="DarkCyan" BorderThickness="1" Name="RenderAreaBorder" RenderOptions.BitmapScalingMode="NearestNeighbor">
<Border.Background>
<ImageBrush
ImageSource="{Binding ., Mode=OneWay, Converter={StaticResource UndertaleCachedImageLoader}, ConverterParameter=nocache}"
TileMode="None"
Stretch="UniformToFill">
TileMode="None" Stretch="None">
</ImageBrush>
</Border.Background>
</Border>
Expand Down
20 changes: 20 additions & 0 deletions UndertaleModTool/Controls/UndertaleTexturePageItemDisplay.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ namespace UndertaleModTool
/// </summary>
public partial class UndertaleTexturePageItemDisplay : UserControl
{
public static readonly DependencyProperty DisplayBorderProperty =
DependencyProperty.Register("DisplayBorder", typeof(bool),
typeof(UndertaleTexturePageItemDisplay),
new FrameworkPropertyMetadata(true,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (sender, e) =>
{
var inst = sender as UndertaleTexturePageItemDisplay;
if (inst is null)
return;
if (e.NewValue is not bool val)
return;

inst.RenderAreaBorder.BorderThickness = new Thickness(val ? 1 : 0);
}));
public bool DisplayBorder
{
get { return (bool)GetValue(DisplayBorderProperty); }
set { SetValue(DisplayBorderProperty, value); }
}

public UndertaleTexturePageItemDisplay()
{
InitializeComponent();
Expand Down
54 changes: 54 additions & 0 deletions UndertaleModTool/Converters/IsVersionAtLeastConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Data;

namespace UndertaleModTool
{
public class IsVersionAtLeastConverter : IValueConverter
{
private static readonly MainWindow mainWindow = Application.Current.MainWindow as MainWindow;
private static readonly Regex versionRegex = new(@"(\d+)\.(\d+)(?:\.(\d+))?(?:\.(\d+))?", RegexOptions.Compiled);

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (mainWindow.Data?.GeneralInfo is null
|| parameter is not string verStr
|| verStr.Length == 0)
return Visibility.Hidden;

var ver = versionRegex.Match(verStr);
if (!ver.Success)
return Visibility.Hidden;
try
{
uint major = uint.Parse(ver.Groups[1].Value);
uint minor = uint.Parse(ver.Groups[2].Value);
uint release = 0;
uint build = 0;
if (ver.Groups[3].Value != "")
release = uint.Parse(ver.Groups[3].Value);
if (ver.Groups[4].Value != "")
release = uint.Parse(ver.Groups[4].Value);

if (mainWindow.Data.IsVersionAtLeast(major, minor, release, build))
return Visibility.Visible;
else
return Visibility.Collapsed;
}
catch
{
return Visibility.Hidden;
}
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
23 changes: 21 additions & 2 deletions UndertaleModTool/Editors/UndertaleBackgroundEditor.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.Resources>
<local:IsVersionAtLeastConverter x:Key="IsVersionAtLeastConverter"/>
</Grid.Resources>

<TextBlock Grid.Row="0" Grid.Column="0" Margin="3">Name</TextBlock>
<local:UndertaleStringReference Grid.Row="0" Grid.Column="1" Margin="3" ObjectReference="{Binding Name}"/>
Expand All @@ -35,7 +38,7 @@
<TextBlock Grid.Row="4" Grid.Column="0" Margin="3">Texture</TextBlock>
<local:UndertaleObjectReference Grid.Row="4" Grid.Column="1" Margin="3" ObjectReference="{Binding Texture}" ObjectType="{x:Type undertale:UndertaleTexturePageItem}"/>

<Grid Grid.Row="5" Grid.ColumnSpan="2" Margin="0" Visibility="{Binding DataContext.IsGMS2, Mode=OneTime, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}">
<Grid Grid.Row="5" Grid.ColumnSpan="2" Margin="0" Visibility="{Binding Mode=OneTime, Converter={StaticResource IsVersionAtLeastConverter}, ConverterParameter=2.0}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="3*"/>
Expand All @@ -52,6 +55,7 @@
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

<TextBlock Grid.Row="0" Grid.Column="0" Margin="3">Unknown Always 2</TextBlock>
Expand Down Expand Up @@ -122,11 +126,26 @@
</DataGridTemplateColumn>
</DataGrid.Columns>
</local:DataGridDark>

<TextBlock Grid.Row="11" Grid.ColumnSpan="2" Margin="3" HorizontalAlignment="Center" Foreground="DarkGray" FontStyle="Italic" TextWrapping="Wrap" TextAlignment="Center">
Hint: You can click on any tile region below to highlight its ID above.
</TextBlock>
</Grid>

<Viewbox Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="2" Stretch="Uniform" StretchDirection="DownOnly">
<Canvas Name="BGTexture" Width="{Binding Texture.BoundingWidth, Mode=OneWay}" Height="{Binding Texture.BoundingHeight, Mode=OneWay}"
<Canvas Name="BGTexture"
Width="{Binding Texture.BoundingWidth, Mode=OneWay}" Height="{Binding Texture.BoundingHeight, Mode=OneWay}"
MouseLeftButtonDown="BGTexture_MouseLeftButtonDown" PreviewMouseRightButtonDown="BGTexture_PreviewMouseRightButtonDown">
<Canvas.Style>
<Style TargetType="Canvas">
<Style.Triggers>
<DataTrigger Binding="{Binding Mode=OneTime, Converter={StaticResource IsVersionAtLeastConverter}, ConverterParameter=2.0}"
Value="Visible">
<Setter Property="Cursor" Value="Hand"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Canvas.Style>
<Border>
<Border.Background>
<DrawingBrush Stretch="None" TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute">
Expand Down
Loading