Skip to content

Commit

Permalink
Handle "resolution" between win and krkr conversion, Fix #75
Browse files Browse the repository at this point in the history
  • Loading branch information
UlyssesWu committed Apr 4, 2022
1 parent 12f6b21 commit 53d7393
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 16 deletions.
53 changes: 51 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,53 @@
[*.cs]
[*.cs]

# CS1591: 缺少对公共可见类型或成员的 XML 注释
dotnet_diagnostic.CS1591.severity = none
dotnet_diagnostic.cs1591.severity = none

# Microsoft .NET properties
csharp_new_line_before_members_in_object_initializers = false
csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:suggestion
csharp_space_after_cast = true
csharp_style_var_elsewhere = true:suggestion
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
dotnet_style_qualification_for_event = false:suggestion
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion

# ReSharper properties
resharper_csharp_max_line_length = 140
resharper_space_within_single_line_array_initializer_braces = false

# ReSharper inspection severities
resharper_arrange_redundant_parentheses_highlighting = hint
resharper_arrange_this_qualifier_highlighting = hint
resharper_arrange_type_member_modifiers_highlighting = hint
resharper_arrange_type_modifiers_highlighting = hint
resharper_built_in_type_reference_style_for_member_access_highlighting = hint
resharper_built_in_type_reference_style_highlighting = hint
resharper_redundant_base_qualifier_highlighting = warning
resharper_suggest_var_or_type_built_in_types_highlighting = hint
resharper_suggest_var_or_type_elsewhere_highlighting = hint
resharper_suggest_var_or_type_simple_types_highlighting = hint

[*.{appxmanifest,axml,build,c,c++,cc,cginc,compute,config,cp,cpp,csproj,cu,cuh,cxx,dbml,discomap,dtd,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,jsproj,lsproj,mpp,mq4,mq5,mqh,njsproj,nuspec,proj,props,proto,resw,resx,StyleCop,targets,tasks,tpp,usf,ush,vbproj,xml,xsd}]
indent_style = tab
indent_size = tab
tab_width = 4

[*.{asax,ascx,aspx,axaml,cs,cshtml,css,htm,html,js,jsx,master,paml,razor,skin,ts,tsx,vb,xaml,xamlx,xoml}]
indent_style = space
indent_size = 4
tab_width = 4

[*.{json,resjson}]
indent_style = space
indent_size = 2
tab_width = 2
39 changes: 39 additions & 0 deletions FreeMote.PsBuild/Converters/Common2KrkrConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using FreeMote.Psb;
using FreeMote.Psb.Textures;
// ReSharper disable CompareOfFloatsByEqualityOperator

namespace FreeMote.PsBuild.Converters
{
Expand Down Expand Up @@ -81,6 +82,44 @@ private Dictionary<string, List<string>> TranslateResources(PSB psb)
{
iconList.Add(iconPair.Key);
var icon = (PsbDictionary) iconPair.Value;
//handle resolution from win
if (icon.ContainsKey("resolution") && icon["resolution"].GetFloat() != 1.0f)
{
//Converting from win to krkr. Win has scaled image, but krkr wants a full size one.
//Scale it up will cause bad quality image most likely. But there seems no other choice.
var resolution = icon["resolution"].GetFloat();
var bmp = bmps[iconPair.Key];
var resizedBmp = bmp.ResizeImage(icon["width"].GetInt(), icon["height"].GetInt());
bmps[iconPair.Key] = resizedBmp;
bmp.Dispose();

//Attempt to remove resolution, won't work
//icon.Remove("resolution"); //you won't be able to convert it back
//if (icon.ContainsKey("width"))
//{
// icon["width"] = new PsbNumber(Math.Ceiling(icon["width"].GetFloat() * resolution));
//}
//if (icon.ContainsKey("height"))
//{
// icon["height"] = new PsbNumber(Math.Ceiling(icon["height"].GetFloat() * resolution));
//}

//if (icon.ContainsKey("originX"))
//{
// icon["originX"] = new PsbNumber(Math.Floor(icon["originX"].GetFloat() * resolution));
//}

//if (icon.ContainsKey("originY"))
//{
// icon["originY"] = new PsbNumber(Math.Floor(icon["originY"].GetFloat() * resolution));
//}
}
else if (icon.ContainsKey("resolution_hint")) //recover resolution
{
icon["resolution"] = icon["resolution_hint"];
icon.Remove("resolution_hint");
}

var data = UseRL
? RL.CompressImage(bmps[iconPair.Key], TargetPixelFormat)
: RL.GetPixelBytesFromImage(bmps[iconPair.Key], TargetPixelFormat);
Expand Down
67 changes: 62 additions & 5 deletions FreeMote.PsBuild/Converters/Krkr2CommonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using FreeMote.Psb;
using FreeMote.Psb.Textures;
// ReSharper disable CompareOfFloatsByEqualityOperator

namespace FreeMote.PsBuild.Converters
{
Expand Down Expand Up @@ -33,8 +35,16 @@ public Krkr2CommonConverter(bool toWin = false)
public int TexturePadding { get; set; } = 5;
public BestFitHeuristic FitHeuristic { get; set; } = BestFitHeuristic.MaxOneAxis;

/// <summary>
/// Use name gained from krkr PSB like "vr足l"
/// </summary>
public bool UseMeaningfulName { get; set; } = true;
/// <summary>
/// If enable, scale down the image to match the target resolution, maybe causing bad quality.
/// <para>If not enable, ignore and remove "resolution" in icon (reset resolution to 1, making the image clear)</para>
/// </summary>
public bool EnableResolution { get; set; } = false;
/// <summary>
/// Expand texture edge
/// </summary>
public TextureEdgeProcess EdgeProcess { get; set; } = TextureEdgeProcess.Expand1Px;
Expand Down Expand Up @@ -150,6 +160,7 @@ void LayerTravel(PsbList collection, List<string> indexList)
var source = (PsbDictionary) psb.Objects["source"];
int maxSideLength = 2048;
long area = 0;
var texRegex = new Regex($"^tex#.+?{Delimiter}");

//Collect textures
foreach (var tex in source)
Expand All @@ -159,6 +170,11 @@ void LayerTravel(PsbList collection, List<string> indexList)
foreach (var icon in icons)
{
var iconName = icon.Key;
var match = texRegex.Match(iconName);
if (match.Success)
{
iconName = iconName.Substring(match.Length);
}
var info = (PsbDictionary) icon.Value;
var width = (int) (PsbNumber) info["width"];
var height = (int) (PsbNumber) info["height"];
Expand All @@ -171,8 +187,20 @@ void LayerTravel(PsbList collection, List<string> indexList)
var bmp = info["compress"]?.ToString().ToUpperInvariant() == "RL"
? RL.DecompressToImage(res.Data, height, width, psb.Platform.DefaultPixelFormat())
: RL.ConvertToImage(res.Data, height, width, psb.Platform.DefaultPixelFormat());
if (info.ContainsKey("resolution") && info["resolution"].GetFloat() != 1.0f && EnableResolution)
{
//scale down image, not recommended
var resolution = info["resolution"].GetFloat();
var newWidth = (int) Math.Ceiling(width * resolution);
var newHeight = (int) Math.Ceiling(height * resolution);
var resizedBmp = bmp.ResizeImage(newWidth, newHeight);
bmp.Dispose();
bmp = resizedBmp;
width = newWidth;
height = newHeight;
}
bmp.Tag = iconName;
textures.Add($"{texName}{Delimiter}{icon.Key}", bmp);
textures.Add($"{texName}{Delimiter}{iconName}", bmp);
//estimate area and side length
area += width * height;
if (width >= maxSideLength || height >= maxSideLength)
Expand All @@ -189,7 +217,7 @@ void LayerTravel(PsbList collection, List<string> indexList)
size = 4096;
}

int padding = TexturePadding >= 0 && TexturePadding <= 100 ? TexturePadding : 1;
int padding = TexturePadding is >= 0 and <= 100 ? TexturePadding : 1;

TexturePacker packer = new TexturePacker
{
Expand Down Expand Up @@ -222,15 +250,44 @@ void LayerTravel(PsbList collection, List<string> indexList)
continue;
}

var paths = node.Texture.Source.Split(new[] {Delimiter}, StringSplitOptions.RemoveEmptyEntries);
var icon = (PsbDictionary) source[paths[0]].Children("icon").Children(paths[1]);
var delimiterPos = node.Texture.Source.IndexOf(Delimiter, StringComparison.Ordinal);
if (delimiterPos < 0)
{
throw new FormatException($"cannot parse icon path: {node.Texture.Source}");
}
var texPath = node.Texture.Source.Substring(0, delimiterPos);
var iconPath = node.Texture.Source.Substring(delimiterPos + 1);
//var paths = node.Texture.Source.Split(new[] {Delimiter}, StringSplitOptions.RemoveEmptyEntries);
var icon = (PsbDictionary) source[texPath].Children("icon").Children(iconPath);
icon.Remove("compress");
icon.Remove(Consts.ResourceKey);
icon["attr"] = PsbNumber.Zero;
icon["left"] = new PsbNumber(node.Bounds.Left);
icon["top"] = new PsbNumber(node.Bounds.Top);
if (icon.ContainsKey("resolution") && icon["resolution"].GetFloat() != 1.0f && !EnableResolution)
{
//Converting from krkr to win. Krkr has the full size image. We just keep resolution = 1.
//Maybe implement scale down later.
var resolution = icon["resolution"].GetFloat();
icon["resolution_hint"] = new PsbNumber(resolution); //leave a hint here
icon.Remove("resolution");
}
icon.Parent = icons;
var iconName = UseMeaningfulName ? node.Texture.Source : id.ToString();
var iconName = id.ToString();
if (UseMeaningfulName)
{
var meaningfulName = node.Texture.Source;
var match = texRegex.Match(meaningfulName);
if (match.Success)
{
meaningfulName = meaningfulName.Substring(match.Length);
}
if (!string.IsNullOrWhiteSpace(meaningfulName) && !icons.ContainsKey(meaningfulName))
{
iconName = meaningfulName;
}
}
//var iconName = UseMeaningfulName ? node.Texture.Source : id.ToString();
icons.Add(iconName, icon);
iconInfos.Add(node.Texture.Source, (texName, iconName));
id++;
Expand Down
14 changes: 9 additions & 5 deletions FreeMote.PsBuild/PsbSpecConverter.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
using FreeMote.Psb;
using FreeMote.Psb.Textures;
using FreeMote.PsBuild.Converters;

namespace FreeMote.PsBuild
{
public static class PsbSpecConverter
{
/// <summary>
/// Enable resolution support (may scaling images, quality is not guaranteed)
/// </summary>
public static bool EnableResolution = false;

/// <summary>
/// Try to switch Spec
/// </summary>
Expand All @@ -15,7 +19,7 @@ public static class PsbSpecConverter
public static void SwitchSpec(this PSB psb, PsbSpec targetSpec,
PsbPixelFormat pixelFormat = PsbPixelFormat.None)
{
if (targetSpec == PsbSpec.other || targetSpec == PsbSpec.none)
if (targetSpec is PsbSpec.other or PsbSpec.none)
{
return;
}
Expand Down Expand Up @@ -66,7 +70,7 @@ public static void SwitchSpec(this PSB psb, PsbSpec targetSpec,
switch (original)
{
case PsbSpec.krkr:
Krkr2CommonConverter krkr2Win = new Krkr2CommonConverter(true);
Krkr2CommonConverter krkr2Win = new Krkr2CommonConverter(true) {EnableResolution = EnableResolution};
krkr2Win.Convert(psb);
break;
case PsbSpec.common:
Expand All @@ -79,12 +83,12 @@ public static void SwitchSpec(this PSB psb, PsbSpec targetSpec,
}
}

else if (targetSpec == PsbSpec.common || targetSpec == PsbSpec.ems)
else if (targetSpec is PsbSpec.common or PsbSpec.ems)
{
switch (original)
{
case PsbSpec.krkr:
Krkr2CommonConverter krkr2Common = new Krkr2CommonConverter();
Krkr2CommonConverter krkr2Common = new Krkr2CommonConverter() {EnableResolution = EnableResolution};
krkr2Common.Convert(psb);
break;
case PsbSpec.win:
Expand Down
13 changes: 13 additions & 0 deletions FreeMote.Psb/Textures/TextureSpliter.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#define USE_FASTBITMAP
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
#if USE_FASTBITMAP
using FastBitmapLib;

// ReSharper disable CompareOfFloatsByEqualityOperator

#else
using System.Drawing.Drawing2D;
#endif
Expand Down Expand Up @@ -76,6 +79,16 @@ public static Dictionary<string, Bitmap> SplitTexture(PsbDictionary tex, PsbSpec
var height = (int) (PsbNumber) info["height"];
var top = (int) (PsbNumber) info["top"];
var left = (int) (PsbNumber) info["left"];
if (info.ContainsKey("resolution")) // the actual width and height need * resolution
{
var resolution = (float) (PsbNumber) info["resolution"];
if (resolution != 1.0f)
{
width = (int) Math.Ceiling(width * resolution);
height = (int) Math.Ceiling(height * resolution);
}
}

Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb);
#if USE_FASTBITMAP
using (FastBitmap f = b.FastLock())
Expand Down
13 changes: 9 additions & 4 deletions FreeMote.Tools.PsBuild/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,21 @@ PsBuild port -p win sample.psb
var optPortSpec = portCmd.Option<PsbSpec>("-p|--spec <SPEC>",
"Target PSB platform (krkr/common/win/ems)",
CommandOptionType.SingleValue).IsRequired();
var optEnableResolution = portCmd.Option<bool>("-r|--resolution",
"Enable resolution support (may scaling images, quality is not guaranteed)", CommandOptionType.NoValue);
//args
var argPsbPath = portCmd.Argument("PSB", "PSB Path", multipleValues: true).IsRequired();

portCmd.OnExecute(() =>
{
var portSpec = optPortSpec.ParsedValue;
var psbPaths = argPsbPath.Values;
var enableResolution = optEnableResolution.HasValue();
foreach (var s in psbPaths)
{
if (File.Exists(s))
{
Port(s, portSpec);
Port(s, portSpec, enableResolution);
}
}
});
Expand Down Expand Up @@ -255,7 +258,7 @@ PsBuild replace sample.psb sample.json
Console.WriteLine("Done.");
}

private static void Port(string s, PsbSpec portSpec)
private static void Port(string s, PsbSpec portSpec, bool resolution = false)
{
var name = Path.GetFileNameWithoutExtension(s);
var ext = Path.GetExtension(s);
Expand All @@ -267,10 +270,12 @@ private static void Port(string s, PsbSpec portSpec)
}
else
{
PsbSpecConverter.EnableResolution = resolution;
psb.SwitchSpec(portSpec);
psb.Merge();
File.WriteAllBytes(Path.ChangeExtension(s, $".{portSpec}{psb.Type.DefaultExtension()}"), psb.Build());
Console.WriteLine($"Convert {name} done.");
var savePath = Path.ChangeExtension(s, $".{portSpec}{psb.Type.DefaultExtension()}");
File.WriteAllBytes(savePath, psb.Build());
Console.WriteLine($"Convert output: {savePath}");
}
}

Expand Down
1 change: 1 addition & 0 deletions FreeMote.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=HEVAG/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Inplace/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kirikiri/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=krkr/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=loopstr/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tachie/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unswizzle/@EntryIndexedValue">True</s:Boolean>
Expand Down
Loading

0 comments on commit 53d7393

Please sign in to comment.