Added parsing background, time, activities and date to models

fonts_experiment
Valeriy Mironov 2017-11-21 18:33:44 +02:00
parent 3ce62f8446
commit d1bacbb62c
28 changed files with 577 additions and 164 deletions

View File

@ -0,0 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/EMPTY_BLOCK_STYLE/@EntryValue">TOGETHER_SAME_LINE</s:String>
<s:String x:Key="/Default/Environment/Hierarchy/PsiConfigurationSettingsKey/CustomLocation/@EntryValue">C:\Users\valeronm\AppData\Local\JetBrains\Transient\ReSharperPlatformVs15\v11_048a238b\SolutionCaches</s:String></wpf:ResourceDictionary>

View File

@ -1,14 +1,14 @@
using System;
using System.IO;
using System.Linq;
using SixLabors.ImageSharp;
using WatchFace;
using WatchFace.Models;
namespace Cmd
{
class Program
internal class Program
{
static void Main(string[] args)
private static void Main(string[] args)
{
var fileName = args[0];
Reader reader;
@ -18,13 +18,20 @@ namespace Cmd
reader = new Reader(fileStream);
reader.Parse();
}
foreach (var resource in reader.Resources)
{
Console.WriteLine("{0:D}: ", resource.Id);
foreach (var descriptor in resource.Descriptor)
{
WriteParameter(4, descriptor);
}
foreach (var descriptor in resource.Children) WriteParameter(4, descriptor);
}
var watchFace = WatchFace.WatchFace.Parse(reader.Resources);
var index = 0;
foreach (var image in reader.Images)
{
image.Save($"{index}.bmp");
index++;
}
Console.ReadKey();
@ -35,13 +42,10 @@ namespace Cmd
for (var i = 0; i < offset; i++)
Console.Write(' ');
Console.Write("{0:D}: ", parameter.Id);
if (parameter.IsList)
if (parameter.IsComplex)
{
Console.WriteLine();
foreach (var parameter1 in parameter.List)
{
WriteParameter(offset + 4, parameter1);
}
foreach (var parameter1 in parameter.Children) WriteParameter(offset + 4, parameter1);
}
else
{
@ -49,4 +53,4 @@ namespace Cmd
}
}
}
}
}

View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using WatchFace.Models;
namespace WatchFace.BasicElements
{
public class AmPmSwitch
{
public long ImageIndexPm { get; set; }
public long ImageIndexAm { get; set; }
public long X { get; set; }
public long Y { get; set; }
public static AmPmSwitch Parse(List<Parameter> descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new AmPmSwitch();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.X = parameter.Value;
break;
case 2:
result.Y = parameter.Value;
break;
case 3:
result.ImageIndexAm = parameter.Value;
break;
case 4:
result.ImageIndexPm = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using WatchFace.Models;
namespace WatchFace.BasicElements
{
public class FormattedNumber
{
public Number Number { get; set; }
public long SuffixImageIndex { get; set; }
public long DecimalPointImageIndex { get; set; }
public static FormattedNumber Parse(List<Parameter> descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new FormattedNumber();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.Number = Number.Parse(parameter.Children);
break;
case 2:
result.SuffixImageIndex = parameter.Value;
break;
case 3:
result.DecimalPointImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using WatchFace.Models;
namespace WatchFace.Elements
{
public class Image
{
public long ImageIndex { get; set; }
public long X { get; set; }
public long Y { get; set; }
public static Image Parse(List<Parameter> descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Image();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.X = parameter.Value;
break;
case 2:
result.Y = parameter.Value;
break;
case 3:
result.ImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using WatchFace.Models;
namespace WatchFace.BasicElements
{
public class ImageSet
{
public long ImageIndex { get; set; }
public long ImagesCount { get; set; }
public long X { get; set; }
public long Y { get; set; }
public static ImageSet Parse(List<Parameter> descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new ImageSet();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.X = parameter.Value;
break;
case 2:
result.Y = parameter.Value;
break;
case 3:
result.ImageIndex = parameter.Value;
break;
case 4:
result.ImagesCount = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using WatchFace.Models;
namespace WatchFace.BasicElements
{
public class JoinedNumber
{
public Number Number { get; set; }
public long DelimiterImageIndex { get; set; }
public static JoinedNumber Parse(List<Parameter> descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new JoinedNumber();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.Number = Number.Parse(parameter.Children);
break;
case 2:
result.DelimiterImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using WatchFace.Models;
namespace WatchFace.BasicElements
{
public class Number
{
public long BottomRightX { get; set; }
public long BottomRightY { get; set; }
public long ImageIndex { get; set; }
public long ImagesCount { get; set; }
public long TopLeftX { get; set; }
public long TopLeftY { get; set; }
public long Unknown1 { get; set; }
public long Unknown2 { get; set; }
public static Number Parse(List<Parameter> descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Number();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.TopLeftX = parameter.Value;
break;
case 2:
result.TopLeftY = parameter.Value;
break;
case 3:
result.BottomRightX = parameter.Value;
break;
case 4:
result.BottomRightY = parameter.Value;
break;
case 5:
result.Unknown1 = parameter.Value;
break;
case 6:
result.Unknown2 = parameter.Value;
break;
case 7:
result.ImageIndex = parameter.Value;
break;
case 8:
result.ImagesCount = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using WatchFace.Models;
namespace WatchFace.BasicElements
{
public class TwoDigits
{
public ImageSet Tens { get; set; }
public ImageSet Ones { get; set; }
public static TwoDigits Parse(List<Parameter> descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new TwoDigits();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.Tens = ImageSet.Parse(parameter.Children);
break;
case 2:
result.Ones = ImageSet.Parse(parameter.Children);
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -1,16 +1,46 @@
namespace WatchFace.Elements
using System;
using System.Collections.Generic;
using WatchFace.BasicElements;
using WatchFace.Models;
namespace WatchFace.Elements
{
public class Activity
{
private Number _calories;
private Number _pulse;
private Number _steps;
public Number Calories { get; set; }
public Number Pulse { get; set; }
public Number Steps { get; set; }
public Number StepsGoal { get; set; }
public FormattedNumber Distance { get; set; }
public Activity(Number steps, Number calories, Number pulse)
public static Activity Parse(List<Parameter> descriptor)
{
_steps = steps;
_calories = calories;
_pulse = pulse;
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Activity();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.Steps = Number.Parse(parameter.Children);
break;
case 2:
result.StepsGoal = Number.Parse(parameter.Children);
break;
case 3:
result.Calories = Number.Parse(parameter.Children);
break;
case 4:
result.Pulse = Number.Parse(parameter.Children);
break;
case 5:
result.Distance = FormattedNumber.Parse(parameter.Children);
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -1,12 +1,25 @@
namespace WatchFace.Elements
using System.Collections.Generic;
using WatchFace.Models;
namespace WatchFace.Elements
{
public class Background
{
private Image _image;
public Image Image { get; set; }
public Background(Image image)
public static Background Parse(List<Parameter> parameters)
{
_image = image;
var result = new Background();
foreach (var parameter in parameters)
switch (parameter.Id)
{
case 1:
result.Image = Image.Parse(parameter.Children);
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using WatchFace.BasicElements;
using WatchFace.Models;
namespace WatchFace.Elements
{
public class Date
{
public MonthAndDay MonthAndDay { get; set; }
public ImageSet WeekDay { get; set; }
public static Date Parse(List<Parameter> descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Date();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.MonthAndDay = MonthAndDay.Parse(parameter.Children);
break;
case 2:
result.WeekDay = ImageSet.Parse(parameter.Children);
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -1,18 +0,0 @@
namespace WatchFace.Elements
{
public class Digit
{
private int _imageIndex;
private int _imagesCount;
private int _x;
private int _y;
public Digit(int x, int y, int imageIndex, int imagesCount)
{
_x = x;
_y = y;
_imageIndex = imageIndex;
_imagesCount = imagesCount;
}
}
}

View File

@ -1,16 +0,0 @@
namespace WatchFace.Elements
{
public class Image
{
private int _imageIndex;
private int _x;
private int _y;
public Image(int x, int y, int imageIndex)
{
_x = x;
_y = y;
_imageIndex = imageIndex;
}
}
}

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using WatchFace.BasicElements;
using WatchFace.Models;
namespace WatchFace.Elements
{
public class MonthAndDay
{
public SeparateMonthAndDay Separate { get; set; }
public JoinedNumber Joined { get; set; }
public long Unknown1 { get; set; }
public long Unknown2 { get; set; }
public static MonthAndDay Parse(List<Parameter> descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new MonthAndDay();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.Separate = SeparateMonthAndDay.Parse(parameter.Children);
break;
case 2:
result.Joined = JoinedNumber.Parse(parameter.Children);
break;
case 3:
result.Unknown1 = parameter.Value;
break;
case 4:
result.Unknown2 = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -1,27 +0,0 @@
namespace WatchFace.Elements
{
public class Number
{
private int _bottomRightX;
private int _bottomRightY;
private int _imageIndex;
private int _imagesCount;
private int _topLeftX;
private int _topLeftY;
private int _unknown1;
private int _unknown2;
public Number(int topLeftX, int topLeftY, int bottomRightX, int bottomRightY, int unknown1, int unknown2,
int imageIndex, int imagesCount)
{
_topLeftX = topLeftX;
_topLeftY = topLeftY;
_bottomRightX = bottomRightX;
_bottomRightY = bottomRightY;
_unknown1 = unknown1;
_unknown2 = unknown2;
_imageIndex = imageIndex;
_imagesCount = imagesCount;
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using WatchFace.BasicElements;
using WatchFace.Models;
namespace WatchFace.Elements
{
public class SeparateMonthAndDay
{
public Number Month { get; set; }
public Number Day { get; set; }
public static SeparateMonthAndDay Parse(List<Parameter> descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new SeparateMonthAndDay();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.Month = Number.Parse(parameter.Children);
break;
case 3:
result.Day = Number.Parse(parameter.Children);
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -1,18 +0,0 @@
namespace WatchFace.Elements
{
public class Switch
{
private int _imageIndexOff;
private int _imageIndexOn;
private int _x;
private int _y;
public Switch(int x, int y, int imageIndexOff, int imageIndexOn)
{
_x = x;
_y = y;
_imageIndexOff = imageIndexOff;
_imageIndexOn = imageIndexOn;
}
}
}

View File

@ -1,18 +1,42 @@
namespace WatchFace.Elements
using System;
using System.Collections.Generic;
using WatchFace.BasicElements;
using WatchFace.Models;
namespace WatchFace.Elements
{
public class Time
{
private Switch _amPm;
private TwoDigits _hours;
private TwoDigits _minutes;
private TwoDigits _seconds;
public AmPmSwitch AmPm { get; set; }
public TwoDigits Hours { get; set; }
public TwoDigits Minutes { get; set; }
public TwoDigits Seconds { get; set; }
public Time(TwoDigits hours, TwoDigits minutes, TwoDigits seconds, Switch amPm)
public static Time Parse(List<Parameter> descriptor)
{
_hours = hours;
_minutes = minutes;
_seconds = seconds;
_amPm = amPm;
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Time();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.Hours = TwoDigits.Parse(parameter.Children);
break;
case 2:
result.Minutes = TwoDigits.Parse(parameter.Children);
break;
case 3:
result.Seconds = TwoDigits.Parse(parameter.Children);
break;
case 4:
result.AmPm = AmPmSwitch.Parse(parameter.Children);
break;
default:
throw new InvalidParameterException(parameter);
}
return result;
}
}
}

View File

@ -1,14 +0,0 @@
namespace WatchFace.Elements
{
public class TwoDigits
{
private Digit _tens;
private Digit _ones;
public TwoDigits(Digit tens, Digit ones)
{
_tens = tens;
_ones = ones;
}
}
}

View File

@ -4,15 +4,15 @@ using System.IO;
using SixLabors.ImageSharp;
using WatchFace.Utils;
namespace WatchFace.Models
namespace WatchFace
{
public class ImageReader
{
private readonly BinaryReader _reader;
private ushort _paletteColors;
private ushort _bitsPerPixel;
private ushort _height;
private List<Rgba32> _palette;
private ushort _paletteColors;
private ushort _rowLengthInBytes;
private ushort _transp;
private ushort _width;

View File

@ -0,0 +1,12 @@
using System;
using WatchFace.Models;
namespace WatchFace
{
public class InvalidParameterException : Exception
{
public InvalidParameterException(Parameter paramter) : base(
$"Parameter with Id: {paramter.Id} is not supported in this position."
) { }
}
}

View File

@ -5,31 +5,30 @@ namespace WatchFace.Models
{
public class Parameter
{
private Parameter(byte id, long value)
public Parameter(byte id, long value)
{
Id = id;
Value = value;
}
private Parameter(byte id, List<Parameter> value)
public Parameter(byte id, List<Parameter> value)
{
Id = id;
List = value;
Children = value;
}
public byte Id { get; }
public long Value { get; }
public List<Parameter> List { get; }
public bool IsList => List != null;
public List<Parameter> Children { get; }
public bool IsComplex => Children != null;
public static Parameter ReadFrom(Stream fileStream)
{
var rawId = fileStream.ReadByte();
var id = (byte)((rawId & 0xf8) >> 3);
var id = (byte) ((rawId & 0xf8) >> 3);
var flags = (ParameterFlags) (rawId & 0x7);
if (flags.HasFlag(ParameterFlags.List))
if (flags.HasFlag(ParameterFlags.hasChildren))
{
var readBytes = fileStream.ReadByte();
var buffer = new byte[readBytes];

View File

@ -6,7 +6,7 @@ namespace WatchFace.Models
public enum ParameterFlags
{
Unknown = 1,
List = 2,
hasChildren = 2,
Unknown2 = 4
}
}

View File

@ -1,16 +0,0 @@
using System.Collections.Generic;
namespace WatchFace.Models
{
public class Resource
{
public Resource(byte id, List<Parameter> descriptor)
{
Id = id;
Descriptor = descriptor;
}
public int Id { get; }
public List<Parameter> Descriptor { get; }
}
}

View File

@ -15,7 +15,7 @@ namespace WatchFace
_fileStream = streamReader;
}
public List<Resource> Resources { get; private set; }
public List<Parameter> Resources { get; private set; }
public List<Image<Rgba32>> Images { get; private set; }
public void Parse()
@ -27,8 +27,8 @@ namespace WatchFace
var mainParam = Parameter.ReadFrom(parametersStream);
var parameters = Parameter.ReadList(parametersStream);
var coordinatesTableSize = mainParam.List[0].Value;
var imagesTableLength = mainParam.List[1].Value;
var coordinatesTableSize = mainParam.Children[0].Value;
var imagesTableLength = mainParam.Children[1].Value;
ParseResources(coordinatesTableSize, parameters);
ParseImages(imagesTableLength);
@ -38,14 +38,14 @@ namespace WatchFace
{
var coordsStream = StreamBlock(_fileStream, (int) coordinatesTableSize);
Resources = new List<Resource>(parameters.Count);
Resources = new List<Parameter>(parameters.Count);
foreach (var parameter in parameters)
{
var descriptorOffset = parameter.List[0].Value;
var descriptorLength = parameter.List[1].Value;
coordsStream.Seek((long) descriptorOffset, SeekOrigin.Begin);
var descriptorOffset = parameter.Children[0].Value;
var descriptorLength = parameter.Children[1].Value;
coordsStream.Seek(descriptorOffset, SeekOrigin.Begin);
var descriptorStream = StreamBlock(coordsStream, (int) descriptorLength);
Resources.Add(new Resource(parameter.Id, Parameter.ReadList(descriptorStream)));
Resources.Add(new Parameter(parameter.Id, Parameter.ReadList(descriptorStream)));
}
}
@ -62,7 +62,6 @@ namespace WatchFace
var imageOffset = BitConverter.ToUInt32(imagesOffsets, i * 4) + imagesOffset;
_fileStream.Seek(imageOffset, SeekOrigin.Begin);
var image = new ImageReader(_fileStream).Read();
image.Save($"{i}.bmp");
Images.Add(image);
}
}

43
WatchFace/WatchFace.cs Normal file
View File

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using WatchFace.Elements;
using WatchFace.Models;
namespace WatchFace
{
public class WatchFace
{
public Background Background { get; private set; }
public Time Time { get; private set; }
public Date Date { get; private set; }
public Activity Activity { get; private set; }
public static WatchFace Parse(List<Parameter> descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new WatchFace();
foreach (var resource in descriptor)
switch (resource.Id)
{
case 2:
result.Background = Background.Parse(resource.Children);
break;
case 3:
result.Time = Time.Parse(resource.Children);
break;
case 4:
result.Activity = Activity.Parse(resource.Children);
break;
case 5:
result.Date = Date.Parse(resource.Children);
break;
//default:
// throw new InvalidParameterException(resource);
}
return result;
}
}
}

View File

@ -14,4 +14,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="Parsers\" />
</ItemGroup>
</Project>