Skip to content

Commit 41097fb

Browse files
committed
#498: In Progress
1 parent 755ac67 commit 41097fb

File tree

4 files changed

+174
-58
lines changed

4 files changed

+174
-58
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using Microsoft.Xna.Framework;
2+
using Microsoft.Xna.Framework.Input;
3+
using System.Collections.Generic;
4+
5+
namespace GdxSkinImport;
6+
7+
public class ColorsCache
8+
{
9+
public Dictionary<string, Color> Colors { get; } = new Dictionary<string, Color>();
10+
11+
public void Add(string key, object value)
12+
{
13+
var asRGB = value as Dictionary<string, object>;
14+
if (asRGB != null)
15+
{
16+
var color = asRGB.ParseColor();
17+
Colors[key] = color;
18+
}
19+
else
20+
{
21+
Colors[key] = Colors[(string)value];
22+
}
23+
}
24+
25+
public Color Get(object value)
26+
{
27+
var asRGB = value as Dictionary<string, object>;
28+
if (asRGB != null)
29+
{
30+
return asRGB.ParseColor();
31+
}
32+
33+
return Colors[(string)value];
34+
}
35+
}
Lines changed: 119 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
using GdxSkinImport.MonoGdx;
2-
using info.lundin.math;
1+
using FontStashSharp;
2+
using GdxSkinImport.MonoGdx;
33
using Microsoft.Xna.Framework;
44
using Microsoft.Xna.Framework.Graphics;
5+
using Myra;
56
using Myra.Graphics2D;
67
using Myra.Graphics2D.TextureAtlases;
78
using Myra.Graphics2D.UI.Styles;
@@ -13,7 +14,7 @@
1314

1415
namespace GdxSkinImport;
1516

16-
public static class Converter
17+
public class Converter
1718
{
1819
private class TintedDrawable
1920
{
@@ -23,71 +24,102 @@ private class TintedDrawable
2324
public override string ToString() => $"{Name}:{Color}";
2425
}
2526

26-
private static TextureRegionAtlas ToMyraAtlas(TextureAtlas gdxAtlas)
27+
private readonly GraphicsDevice _device;
28+
private readonly string _path;
29+
private readonly string _folder;
30+
private readonly Stylesheet _result = new Stylesheet();
31+
private TextureRegionAtlas _atlas;
32+
private readonly ColorsCache _colors = new ColorsCache();
33+
private readonly Dictionary<string, SpriteFontBase> _fonts = new Dictionary<string, SpriteFontBase>();
34+
private readonly Dictionary<string, TintedDrawable> _tintedDrawables = new Dictionary<string, TintedDrawable>();
35+
36+
public Converter(GraphicsDevice device, string path)
2737
{
28-
if (gdxAtlas.Textures.Count > 1)
38+
if (string.IsNullOrEmpty(path))
2939
{
30-
throw new NotSupportedException("Only atlases with a single texture are supported");
40+
throw new ArgumentNullException(nameof(path));
3141
}
3242

33-
var result = new TextureRegionAtlas();
43+
_device = device ?? throw new ArgumentNullException(nameof(device));
44+
_path = path;
45+
_folder = Path.GetDirectoryName(this._path);
46+
}
3447

35-
var sourceTexture = gdxAtlas.Textures.First();
48+
public Stylesheet Process()
49+
{
50+
TextureAtlas gdxAtlas = null;
51+
var gdxAtlasFile = Path.ChangeExtension(_path, "atlas");
52+
if (File.Exists(gdxAtlasFile))
53+
{
54+
gdxAtlas = new TextureAtlas(_device, gdxAtlasFile);
55+
}
3656

37-
result.Image = Path.GetFileName(sourceTexture.TexturePath);
57+
_atlas = ToMyraAtlas(gdxAtlas);
3858

39-
foreach(var sourceRegion in gdxAtlas.Regions)
59+
Dictionary<string, object> data;
60+
using (TextReader reader = new StreamReader(_path))
4061
{
41-
var bounds = new Rectangle(sourceRegion.RegionX, sourceRegion.RegionY, sourceRegion.RegionWidth, sourceRegion.RegionHeight);
62+
data = Json.Deserialize(reader) as Dictionary<string, object>;
63+
}
4264

43-
TextureRegion region;
44-
if (sourceRegion.Splits == null)
45-
{
46-
region = new TextureRegion(sourceTexture.Texture, bounds);
47-
}
48-
else
49-
{
50-
var parts = sourceRegion.Splits;
51-
var thickness = new Thickness
52-
{
53-
Left = parts[0],
54-
Right = parts[1],
55-
Top = parts[2],
56-
Bottom = parts[3]
57-
};
65+
var folder = Path.GetDirectoryName(_path);
5866

59-
region = new NinePatchRegion(sourceTexture.Texture, bounds, thickness);
60-
}
67+
return ToMyraStylesheet(data);
68+
}
6169

62-
result.Regions[sourceRegion.Name] = region;
70+
private SpriteFontBase GetFont(string key)
71+
{
72+
SpriteFontBase result;
73+
if (!_fonts.TryGetValue(key, out result))
74+
{
75+
throw new Exception($"Could not find font '{key}'");
6376
}
6477

6578
return result;
6679
}
6780

68-
private static Stylesheet ToMyraStylesheet(Dictionary<string, object> data)
81+
private Color GetColor(Dictionary<string, object> data, string key) => _colors.Get(data[key]);
82+
83+
private void LoadLabelStyle(Dictionary<string, object> data, LabelStyle style)
6984
{
70-
var colors = new Dictionary<string, Color>();
85+
style.Font = GetFont(data.GetString("font"));
86+
style.TextColor = GetColor(data, "fontColor");
87+
}
7188

89+
private Stylesheet ToMyraStylesheet(Dictionary<string, object> data)
90+
{
7291
object obj;
7392
if (data.TryGetValue("com.badlogic.gdx.graphics.Color", out obj))
7493
{
7594
var colorsData = (Dictionary<string, object>)obj;
7695
foreach (var pair in colorsData)
7796
{
78-
var asRGB = pair.Value as Dictionary<string, object>;
79-
if (asRGB != null)
80-
{
81-
var color = asRGB.ParseColor();
82-
colors[pair.Key] = color;
83-
} else
97+
_colors.Add(pair.Key, pair.Value);
98+
}
99+
}
100+
101+
if (data.TryGetValue("com.badlogic.gdx.graphics.g2d.BitmapFont", out obj))
102+
{
103+
var fontsData = (Dictionary<string, object>)obj;
104+
foreach (var pair in fontsData)
105+
{
106+
var f = (Dictionary<string, object>)pair.Value;
107+
108+
var file = f["file"].ToString();
109+
var path = Path.Combine(_folder, file);
110+
111+
var fontData = File.ReadAllText(path);
112+
var font = StaticSpriteFont.FromBMFont(fontData, s =>
84113
{
85-
colors[pair.Key] = colors[(string)pair.Value];
86-
}
114+
var region = _atlas[Path.GetFileNameWithoutExtension(s)];
115+
116+
return new TextureWithOffset(region.Texture, region.Bounds.Location);
117+
});
118+
119+
_fonts[pair.Key] = font;
87120
}
88121
}
89122

90-
var tintedDrawables = new Dictionary<string, TintedDrawable>();
91123
if (data.TryGetValue("com.badlogic.gdx.scenes.scene2d.ui.Skin$TintedDrawable", out obj))
92124
{
93125
var tintedData = (Dictionary<string, object>)obj;
@@ -98,33 +130,67 @@ private static Stylesheet ToMyraStylesheet(Dictionary<string, object> data)
98130
var td = new TintedDrawable
99131
{
100132
Name = (string)v["name"],
101-
Color = colors[(string)v["color"]]
133+
Color = GetColor(v, "color")
102134
};
103135

104-
tintedDrawables[pair.Key] = td;
136+
_tintedDrawables[pair.Key] = td;
137+
}
138+
}
139+
140+
if (data.TryGetValue("com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle", out obj))
141+
{
142+
var widgetData = (Dictionary<string, object>)obj;
143+
foreach (var pair in widgetData)
144+
{
145+
var labelStyle = new LabelStyle();
146+
LoadLabelStyle((Dictionary<string, object>)pair.Value, labelStyle);
147+
148+
_result.LabelStyles[pair.Key] = labelStyle;
105149
}
106150
}
107151

108152
return null;
109153
}
110154

111-
public static Stylesheet ImportGdx(GraphicsDevice device, string path)
155+
private static TextureRegionAtlas ToMyraAtlas(TextureAtlas gdxAtlas)
112156
{
113-
TextureAtlas gdxAtlas = null;
114-
var gdxAtlasFile = Path.ChangeExtension(path, "atlas");
115-
if (File.Exists(gdxAtlasFile))
157+
if (gdxAtlas.Textures.Count > 1)
116158
{
117-
gdxAtlas = new TextureAtlas(device, gdxAtlasFile);
159+
throw new NotSupportedException("Only atlases with a single texture are supported");
118160
}
119161

120-
var myraAtlas = ToMyraAtlas(gdxAtlas);
162+
var result = new TextureRegionAtlas();
121163

122-
Dictionary<string, object> data;
123-
using (TextReader reader = new StreamReader(path))
164+
var sourceTexture = gdxAtlas.Textures.First();
165+
166+
result.Image = Path.GetFileName(sourceTexture.TexturePath);
167+
168+
foreach (var sourceRegion in gdxAtlas.Regions)
124169
{
125-
data = Json.Deserialize(reader) as Dictionary<string, object>;
170+
var bounds = new Rectangle(sourceRegion.RegionX, sourceRegion.RegionY, sourceRegion.RegionWidth, sourceRegion.RegionHeight);
171+
172+
TextureRegion region;
173+
if (sourceRegion.Splits == null)
174+
{
175+
region = new TextureRegion(sourceTexture.Texture, bounds);
176+
}
177+
else
178+
{
179+
var parts = sourceRegion.Splits;
180+
var thickness = new Thickness
181+
{
182+
Left = parts[0],
183+
Right = parts[1],
184+
Top = parts[2],
185+
Bottom = parts[3]
186+
};
187+
188+
region = new NinePatchRegion(sourceTexture.Texture, bounds, thickness);
189+
}
190+
191+
result.Regions[sourceRegion.Name] = region;
126192
}
127-
128-
return ToMyraStylesheet(data);
193+
194+
return result;
129195
}
130196
}

src/Myra.GdxSkinImport/Game1.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ protected override void LoadContent()
3434
{
3535
MyraEnvironment.Game = this;
3636

37-
var stylesheet = Converter.ImportGdx(GraphicsDevice, _inputFile);
37+
var converter = new Converter(GraphicsDevice, _inputFile);
38+
39+
var stylesheet = converter.Process();
3840

3941
Exit();
4042
}

src/Myra.GdxSkinImport/Utility.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,24 @@ public static string TryToMakePathRelativeTo(string path, string pathRelativeTo)
4141
return path;
4242
}
4343

44+
public static float ParseFloat(this Dictionary<string, object> data, string key, float def = 0.0f)
45+
{
46+
object obj;
47+
if (!data.TryGetValue(key, out obj))
48+
{
49+
return def;
50+
}
51+
52+
return float.Parse(obj.ToString());
53+
}
54+
4455
public static Color ParseColor(this Dictionary<string, object> data)
4556
{
46-
return new Color(float.Parse(data["r"].ToString()),
47-
float.Parse(data["g"].ToString()),
48-
float.Parse(data["b"].ToString()),
49-
float.Parse(data["a"].ToString()));
57+
return new Color(data.ParseFloat("r"),
58+
data.ParseFloat("g"),
59+
data.ParseFloat("b"),
60+
data.ParseFloat("a"));
5061
}
62+
63+
public static string GetString(this Dictionary<string, object> data, string key) => data[key].ToString();
5164
}

0 commit comments

Comments
 (0)