feat: Initial commit
This commit is contained in:
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
###############################################################################
|
||||||
|
# Set default behavior to automatically normalize line endings.
|
||||||
|
###############################################################################
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior for command prompt diff.
|
||||||
|
#
|
||||||
|
# This is need for earlier builds of msysgit that does not have it on by
|
||||||
|
# default for csharp files.
|
||||||
|
# Note: This is only used by command line
|
||||||
|
###############################################################################
|
||||||
|
#*.cs diff=csharp
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set the merge driver for project and solution files
|
||||||
|
#
|
||||||
|
# Merging from the command prompt will add diff markers to the files if there
|
||||||
|
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||||
|
# the diff markers are never inserted). Diff markers may cause the following
|
||||||
|
# file extensions to fail to load in VS. An alternative would be to treat
|
||||||
|
# these files as binary and thus will always conflict and require user
|
||||||
|
# intervention with every merge. To do so, just uncomment the entries below
|
||||||
|
###############################################################################
|
||||||
|
#*.sln merge=binary
|
||||||
|
#*.csproj merge=binary
|
||||||
|
#*.vbproj merge=binary
|
||||||
|
#*.vcxproj merge=binary
|
||||||
|
#*.vcproj merge=binary
|
||||||
|
#*.dbproj merge=binary
|
||||||
|
#*.fsproj merge=binary
|
||||||
|
#*.lsproj merge=binary
|
||||||
|
#*.wixproj merge=binary
|
||||||
|
#*.modelproj merge=binary
|
||||||
|
#*.sqlproj merge=binary
|
||||||
|
#*.wwaproj merge=binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# behavior for image files
|
||||||
|
#
|
||||||
|
# image files are treated as binary by default.
|
||||||
|
###############################################################################
|
||||||
|
#*.jpg binary
|
||||||
|
#*.png binary
|
||||||
|
#*.gif binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# diff behavior for common document formats
|
||||||
|
#
|
||||||
|
# Convert binary document formats to text before diffing them. This feature
|
||||||
|
# is only available from the command line. Turn it on by uncommenting the
|
||||||
|
# entries below.
|
||||||
|
###############################################################################
|
||||||
|
#*.doc diff=astextplain
|
||||||
|
#*.DOC diff=astextplain
|
||||||
|
#*.docx diff=astextplain
|
||||||
|
#*.DOCX diff=astextplain
|
||||||
|
#*.dot diff=astextplain
|
||||||
|
#*.DOT diff=astextplain
|
||||||
|
#*.pdf diff=astextplain
|
||||||
|
#*.PDF diff=astextplain
|
||||||
|
#*.rtf diff=astextplain
|
||||||
|
#*.RTF diff=astextplain
|
||||||
63
.gitignore
vendored
Normal file
63
.gitignore
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# This .gitignore file should be placed at the root of your Unity project directory
|
||||||
|
#
|
||||||
|
# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore
|
||||||
|
#
|
||||||
|
/[Ll]ibrary/
|
||||||
|
/[Tt]emp/
|
||||||
|
/[Oo]bj/
|
||||||
|
/[Bb]uild/
|
||||||
|
/[Bb]uilds/
|
||||||
|
/[Ll]ogs/
|
||||||
|
/[Mm]emoryCaptures/
|
||||||
|
|
||||||
|
# Asset meta data should only be ignored when the corresponding asset is also ignored
|
||||||
|
!/[Aa]ssets/**/*.meta
|
||||||
|
|
||||||
|
# Uncomment this line if you wish to ignore the asset store tools plugin
|
||||||
|
# /[Aa]ssets/AssetStoreTools*
|
||||||
|
|
||||||
|
# Autogenerated Jetbrains Rider plugin
|
||||||
|
[Aa]ssets/Plugins/Editor/JetBrains*
|
||||||
|
|
||||||
|
# Visual Studio cache directory
|
||||||
|
.vs/
|
||||||
|
|
||||||
|
# Gradle cache directory
|
||||||
|
.gradle/
|
||||||
|
|
||||||
|
# Autogenerated VS/MD/Consulo solution and project files
|
||||||
|
ExportedObj/
|
||||||
|
.consulo/
|
||||||
|
*.csproj
|
||||||
|
*.unityproj
|
||||||
|
*.sln
|
||||||
|
*.suo
|
||||||
|
*.tmp
|
||||||
|
*.user
|
||||||
|
*.userprefs
|
||||||
|
*.pidb
|
||||||
|
*.booproj
|
||||||
|
*.svd
|
||||||
|
*.pdb
|
||||||
|
*.mdb
|
||||||
|
*.opendb
|
||||||
|
*.VC.db
|
||||||
|
|
||||||
|
# Unity3D generated meta files
|
||||||
|
*.pidb.meta
|
||||||
|
*.pdb.meta
|
||||||
|
*.mdb.meta
|
||||||
|
|
||||||
|
# Unity3D generated file on crash reports
|
||||||
|
sysinfo.txt
|
||||||
|
|
||||||
|
# Builds
|
||||||
|
*.apk
|
||||||
|
*.unitypackage
|
||||||
|
|
||||||
|
# Crashlytics generated file
|
||||||
|
crashlytics-build.properties
|
||||||
|
|
||||||
|
#
|
||||||
|
/Local
|
||||||
|
/UserSettings
|
||||||
6
.vsconfig
Normal file
6
.vsconfig
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0",
|
||||||
|
"components": [
|
||||||
|
"Microsoft.VisualStudio.Workload.ManagedGame"
|
||||||
|
]
|
||||||
|
}
|
||||||
8
Assets/Cryville.Common.meta
Normal file
8
Assets/Cryville.Common.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9a556074c98d68643a16692f7f3af693
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
16
Assets/Cryville.Common/Cryville.Common.asmdef
Normal file
16
Assets/Cryville.Common/Cryville.Common.asmdef
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "Cryville.Common",
|
||||||
|
"rootNamespace": "",
|
||||||
|
"references": [
|
||||||
|
"GUID:da293eebbcb9a4947a212534c52d1a32"
|
||||||
|
],
|
||||||
|
"includePlatforms": [],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [],
|
||||||
|
"autoReferenced": false,
|
||||||
|
"defineConstraints": [],
|
||||||
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
|
}
|
||||||
7
Assets/Cryville.Common/Cryville.Common.asmdef.meta
Normal file
7
Assets/Cryville.Common/Cryville.Common.asmdef.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b92f9c7ac10b1c04e86fc48210f62ab1
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Cryville.Common/Font.meta
Normal file
8
Assets/Cryville.Common/Font.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6e89e0a49233f9e48a97ca7751345a54
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
113
Assets/Cryville.Common/Font/FontFile.cs
Normal file
113
Assets/Cryville.Common/Font/FontFile.cs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
using Cryville.Common.IO;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Cryville.Common.Font {
|
||||||
|
public abstract class FontFile : IEnumerable<Typeface> {
|
||||||
|
public abstract int Count { get; }
|
||||||
|
public abstract Typeface this[int index] { get; }
|
||||||
|
protected FileInfo File { get; private set; }
|
||||||
|
protected BinaryReader Reader { get; private set; }
|
||||||
|
public FontFile(FileInfo file) {
|
||||||
|
File = file;
|
||||||
|
Reader = new BinaryReaderBE(new FileStream(file.FullName, FileMode.Open, FileAccess.Read));
|
||||||
|
}
|
||||||
|
public void Close() { Reader.Close(); }
|
||||||
|
|
||||||
|
public static FontFile Create(FileInfo file) {
|
||||||
|
switch (file.Extension) {
|
||||||
|
case ".ttf": case ".otf": return new FontFileTTF(file);
|
||||||
|
case ".ttc": case ".otc": return new FontFileTTC(file);
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumerator GetEnumerator() {
|
||||||
|
return new Enumerator(this);
|
||||||
|
}
|
||||||
|
IEnumerator<Typeface> IEnumerable<Typeface>.GetEnumerator() {
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() {
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Enumerator : IEnumerator<Typeface> {
|
||||||
|
readonly FontFile _self;
|
||||||
|
int _index;
|
||||||
|
internal Enumerator(FontFile self) {
|
||||||
|
_self = self;
|
||||||
|
_index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Typeface Current {
|
||||||
|
get {
|
||||||
|
if (_index < 0)
|
||||||
|
throw new InvalidOperationException(_index == -1 ? "Enum not started" : "Enum ended");
|
||||||
|
return _self[_index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object IEnumerator.Current { get { return Current; } }
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
_index = -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext() {
|
||||||
|
if (_index == -2) return false;
|
||||||
|
_index++;
|
||||||
|
if (_index >= _self.Count) {
|
||||||
|
_index = -2;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset() {
|
||||||
|
_index = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class FontFileTTF : FontFile {
|
||||||
|
public override int Count { get { return 1; } }
|
||||||
|
public override Typeface this[int index] {
|
||||||
|
get {
|
||||||
|
if (index != 0) throw new ArgumentOutOfRangeException("index");
|
||||||
|
try {
|
||||||
|
return new TypefaceTTF(Reader, File, index);
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
throw new InvalidDataException("Invalid font");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public FontFileTTF(FileInfo file) : base(file) { }
|
||||||
|
}
|
||||||
|
public class FontFileTTC : FontFile {
|
||||||
|
readonly IReadOnlyList<uint> _offsets;
|
||||||
|
public override int Count { get { return _offsets.Count; } }
|
||||||
|
public override Typeface this[int index] {
|
||||||
|
get {
|
||||||
|
if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException("index");
|
||||||
|
Reader.BaseStream.Position = _offsets[index];
|
||||||
|
try {
|
||||||
|
return new TypefaceTTF(Reader, File, index);
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
throw new InvalidDataException("Invalid font");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public FontFileTTC(FileInfo file) : base(file) {
|
||||||
|
try {
|
||||||
|
_offsets = new TTCHeader(Reader, 0).GetItems();
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
throw new InvalidDataException("Invalid font");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Cryville.Common/Font/FontFile.cs.meta
Normal file
11
Assets/Cryville.Common/Font/FontFile.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c1804280aa04fb744a331a1d2dc0066b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
64
Assets/Cryville.Common/Font/FontManager.cs
Normal file
64
Assets/Cryville.Common/Font/FontManager.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Cryville.Common.Font {
|
||||||
|
public abstract class FontManager {
|
||||||
|
public IReadOnlyDictionary<string, Typeface> MapFullNameToTypeface { get; private set; }
|
||||||
|
public IReadOnlyDictionary<string, IReadOnlyCollection<Typeface>> MapNameToTypefaces { get; private set; }
|
||||||
|
public FontManager() {
|
||||||
|
var map1 = new Dictionary<string, Typeface>();
|
||||||
|
var map2 = new Dictionary<string, List<Typeface>>();
|
||||||
|
foreach (var f in EnumerateAllTypefaces()) {
|
||||||
|
if (!map1.ContainsKey(f.FullName)) {
|
||||||
|
map1.Add(f.FullName, f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<Typeface> set2;
|
||||||
|
if (!map2.TryGetValue(f.FamilyName, out set2)) {
|
||||||
|
map2.Add(f.FamilyName, set2 = new List<Typeface>());
|
||||||
|
}
|
||||||
|
set2.Add(f);
|
||||||
|
}
|
||||||
|
MapFullNameToTypeface = map1;
|
||||||
|
MapNameToTypefaces = map2.ToDictionary(i => i.Key, i => (IReadOnlyCollection<Typeface>)i.Value);
|
||||||
|
}
|
||||||
|
protected abstract IEnumerable<Typeface> EnumerateAllTypefaces();
|
||||||
|
protected static IEnumerable<Typeface> ScanDirectoryForTypefaces(string dir) {
|
||||||
|
foreach (var f in new DirectoryInfo(dir).EnumerateFiles()) {
|
||||||
|
FontFile file;
|
||||||
|
try {
|
||||||
|
file = FontFile.Create(f);
|
||||||
|
}
|
||||||
|
catch (InvalidDataException) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (file == null) continue;
|
||||||
|
var enumerator = file.GetEnumerator();
|
||||||
|
while (enumerator.MoveNext()) {
|
||||||
|
Typeface ret;
|
||||||
|
try {
|
||||||
|
ret = enumerator.Current;
|
||||||
|
}
|
||||||
|
catch (InvalidDataException) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
yield return ret;
|
||||||
|
}
|
||||||
|
file.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class FontManagerAndroid : FontManager {
|
||||||
|
protected override IEnumerable<Typeface> EnumerateAllTypefaces() {
|
||||||
|
return ScanDirectoryForTypefaces("/system/fonts");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class FontManagerWindows : FontManager {
|
||||||
|
protected override IEnumerable<Typeface> EnumerateAllTypefaces() {
|
||||||
|
return ScanDirectoryForTypefaces("C:/Windows/Fonts");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Cryville.Common/Font/FontManager.cs.meta
Normal file
11
Assets/Cryville.Common/Font/FontManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9fd2cf4e5a96f5146a8b950c3647e4c9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
343
Assets/Cryville.Common/Font/FontMatcher.cs
Normal file
343
Assets/Cryville.Common/Font/FontMatcher.cs
Normal file
File diff suppressed because it is too large
Load Diff
11
Assets/Cryville.Common/Font/FontMatcher.cs.meta
Normal file
11
Assets/Cryville.Common/Font/FontMatcher.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 157390bd8c4b14243b9109b88480a1c6
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
256
Assets/Cryville.Common/Font/FontTable.cs
Normal file
256
Assets/Cryville.Common/Font/FontTable.cs
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
#pragma warning disable IDE0049
|
||||||
|
namespace Cryville.Common.Font {
|
||||||
|
public abstract class FontTable<T> {
|
||||||
|
protected UInt32 Offset { get; private set; }
|
||||||
|
protected BinaryReader Reader { get; private set; }
|
||||||
|
|
||||||
|
protected FontTable(BinaryReader reader, UInt32 offset) {
|
||||||
|
Reader = reader;
|
||||||
|
Offset = offset;
|
||||||
|
reader.BaseStream.Position = offset;
|
||||||
|
}
|
||||||
|
public abstract IReadOnlyList<T> GetItems();
|
||||||
|
}
|
||||||
|
public abstract class FontTable<T, U> : FontTable<T> {
|
||||||
|
protected FontTable(BinaryReader reader, UInt32 offset) : base(reader, offset) { }
|
||||||
|
public abstract U GetSubTable(T item);
|
||||||
|
}
|
||||||
|
public sealed class TTCHeader : FontTable<UInt32, TableDirectory> {
|
||||||
|
readonly String ttcTag;
|
||||||
|
readonly UInt16 majorVersion;
|
||||||
|
readonly UInt16 minorVersion;
|
||||||
|
readonly UInt32 numFonts;
|
||||||
|
readonly List<UInt32> tableDirectoryOffsets = new List<UInt32>();
|
||||||
|
#pragma warning disable IDE0052 // Reserved
|
||||||
|
readonly String dsigTag;
|
||||||
|
readonly UInt32 dsigLength;
|
||||||
|
readonly UInt32 dsigOffset;
|
||||||
|
#pragma warning restore IDE0052 // Reserved
|
||||||
|
public TTCHeader(BinaryReader reader, UInt32 offset) : base(reader, offset) {
|
||||||
|
ttcTag = reader.ReadTag();
|
||||||
|
if (ttcTag != "ttcf") throw new NotSupportedException();
|
||||||
|
majorVersion = reader.ReadUInt16();
|
||||||
|
minorVersion = reader.ReadUInt16();
|
||||||
|
if (minorVersion != 0) throw new NotSupportedException();
|
||||||
|
numFonts = reader.ReadUInt32();
|
||||||
|
for (UInt32 i = 0; i < numFonts; i++) tableDirectoryOffsets.Add(reader.ReadUInt32());
|
||||||
|
if (majorVersion == 2) {
|
||||||
|
dsigTag = reader.ReadTag();
|
||||||
|
dsigLength = reader.ReadUInt32();
|
||||||
|
dsigOffset = reader.ReadUInt32();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override IReadOnlyList<UInt32> GetItems() {
|
||||||
|
return tableDirectoryOffsets;
|
||||||
|
}
|
||||||
|
public override TableDirectory GetSubTable(UInt32 item) {
|
||||||
|
var i = item;
|
||||||
|
return new TableDirectory(Reader, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public sealed class TableDirectory : FontTable<TableRecord, object> {
|
||||||
|
readonly UInt32 sfntVersion;
|
||||||
|
readonly UInt16 numTables;
|
||||||
|
#pragma warning disable IDE0052 // Reserved
|
||||||
|
readonly UInt16 searchRange;
|
||||||
|
readonly UInt16 entrySelector;
|
||||||
|
readonly UInt16 rangeShift;
|
||||||
|
#pragma warning restore IDE0052 // Reserved
|
||||||
|
readonly List<TableRecord> tableRecords = new List<TableRecord>();
|
||||||
|
public TableDirectory(BinaryReader reader, UInt32 offset) : base(reader, offset) {
|
||||||
|
sfntVersion = reader.ReadUInt32();
|
||||||
|
if (sfntVersion != 0x00010000 && sfntVersion != 0x4F54544F &&
|
||||||
|
sfntVersion != 0x74727565 && sfntVersion != 0x74797031) throw new NotSupportedException();
|
||||||
|
numTables = reader.ReadUInt16();
|
||||||
|
searchRange = reader.ReadUInt16();
|
||||||
|
entrySelector = reader.ReadUInt16();
|
||||||
|
rangeShift = reader.ReadUInt16();
|
||||||
|
for (int i = 0; i < numTables; i++)
|
||||||
|
tableRecords.Add(new TableRecord {
|
||||||
|
tableTag = reader.ReadTag(),
|
||||||
|
checksum = reader.ReadUInt32(),
|
||||||
|
offset = reader.ReadUInt32(),
|
||||||
|
length = reader.ReadUInt32(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public override IReadOnlyList<TableRecord> GetItems() {
|
||||||
|
return tableRecords;
|
||||||
|
}
|
||||||
|
public override object GetSubTable(TableRecord item) {
|
||||||
|
switch (item.tableTag) {
|
||||||
|
case "name": return new NameTable(Reader, item.offset);
|
||||||
|
case "meta": return new MetaTable(Reader, item.offset);
|
||||||
|
default: throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct TableRecord {
|
||||||
|
public string tableTag;
|
||||||
|
public UInt32 checksum;
|
||||||
|
public UInt32 offset;
|
||||||
|
public UInt32 length;
|
||||||
|
}
|
||||||
|
public sealed class NameTable : FontTable<NameRecord> {
|
||||||
|
readonly UInt16 version;
|
||||||
|
readonly UInt16 count;
|
||||||
|
readonly UInt16 storageOffset;
|
||||||
|
readonly List<NameRecord> nameRecord = new List<NameRecord>();
|
||||||
|
readonly UInt16 langTagCount;
|
||||||
|
readonly List<LangTagRecord> langTagRecord = new List<LangTagRecord>();
|
||||||
|
public NameTable(BinaryReader reader, UInt32 offset) : base(reader, offset) {
|
||||||
|
version = reader.ReadUInt16();
|
||||||
|
count = reader.ReadUInt16();
|
||||||
|
storageOffset = reader.ReadUInt16();
|
||||||
|
for (UInt16 i = 0; i < count; i++)
|
||||||
|
nameRecord.Add(new NameRecord(
|
||||||
|
reader.ReadUInt16(),
|
||||||
|
reader.ReadUInt16(),
|
||||||
|
reader.ReadUInt16(),
|
||||||
|
(NameID)reader.ReadUInt16(),
|
||||||
|
reader.ReadUInt16(),
|
||||||
|
reader.ReadUInt16()
|
||||||
|
));
|
||||||
|
if (version == 1) {
|
||||||
|
langTagCount = reader.ReadUInt16();
|
||||||
|
for (UInt16 i = 0; i < langTagCount; i++)
|
||||||
|
langTagRecord.Add(new LangTagRecord(
|
||||||
|
reader.ReadUInt16(),
|
||||||
|
reader.ReadUInt16()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
foreach (var i in nameRecord)
|
||||||
|
i.Load(reader, offset + storageOffset);
|
||||||
|
if (version == 1) {
|
||||||
|
foreach (var i in langTagRecord)
|
||||||
|
i.Load(reader, offset + storageOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public sealed override IReadOnlyList<NameRecord> GetItems() {
|
||||||
|
return nameRecord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class NameRecord {
|
||||||
|
public UInt16 PlatformID { get; private set; }
|
||||||
|
public UInt16 EncodingID { get; private set; }
|
||||||
|
public UInt16 LanguageID { get; private set; }
|
||||||
|
public NameID NameID { get; private set; }
|
||||||
|
public UInt16 Length { get; private set; }
|
||||||
|
public UInt16 StringOffset { get; private set; }
|
||||||
|
public String Value { get; private set; }
|
||||||
|
public NameRecord(UInt16 platformID, UInt16 encodingID, UInt16 languageID, NameID nameID, UInt16 length, UInt16 stringOffset) {
|
||||||
|
PlatformID = platformID;
|
||||||
|
EncodingID = encodingID;
|
||||||
|
LanguageID = languageID;
|
||||||
|
NameID = nameID;
|
||||||
|
Length = length;
|
||||||
|
StringOffset = stringOffset;
|
||||||
|
}
|
||||||
|
public void Load(BinaryReader reader, UInt32 origin) {
|
||||||
|
reader.BaseStream.Position = origin + StringOffset;
|
||||||
|
Encoding encoding;
|
||||||
|
try {
|
||||||
|
switch (PlatformID) {
|
||||||
|
case 0: encoding = Encoding.BigEndianUnicode; break;
|
||||||
|
case 1: encoding = Encoding.GetEncoding(10000 + EncodingID); break;
|
||||||
|
case 3: encoding = Encoding.BigEndianUnicode; break;
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NotSupportedException) { return; }
|
||||||
|
catch (ArgumentException) { return; }
|
||||||
|
Value = encoding.GetString(reader.ReadBytes(Length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public enum NameID : UInt16 {
|
||||||
|
CopyrightNotice = 0,
|
||||||
|
FontFamilyName = 1,
|
||||||
|
FontSubfamilyName = 2,
|
||||||
|
UniqueFontIdentifier = 3,
|
||||||
|
FullFontName = 4,
|
||||||
|
VersionString = 5,
|
||||||
|
PostScriptName = 6,
|
||||||
|
Trademark = 7,
|
||||||
|
ManufacturerName = 8,
|
||||||
|
Designer = 9,
|
||||||
|
Description = 10,
|
||||||
|
URLVendor = 11,
|
||||||
|
URLDesigner = 12,
|
||||||
|
LicenseDescription = 13,
|
||||||
|
LicenseInfoURL = 14,
|
||||||
|
|
||||||
|
TypographicFamilyName = 16,
|
||||||
|
TypographicSubfamilyName = 17,
|
||||||
|
CompatibleFull = 18,
|
||||||
|
SampleText = 19,
|
||||||
|
PostScriptCIDFindfontName = 20,
|
||||||
|
WWSFamilyName = 21,
|
||||||
|
WWSSubfamilyName = 22,
|
||||||
|
LightBackgroundPalette = 23,
|
||||||
|
DarkBackgroundPalette = 24,
|
||||||
|
VariationsPostScriptNamePrefix = 25,
|
||||||
|
}
|
||||||
|
public class LangTagRecord {
|
||||||
|
public UInt16 Length { get; private set; }
|
||||||
|
public UInt16 LangTagOffset { get; private set; }
|
||||||
|
public String Value { get; private set; }
|
||||||
|
public LangTagRecord(UInt16 length, UInt16 langTagOffset) {
|
||||||
|
Length = length;
|
||||||
|
LangTagOffset = langTagOffset;
|
||||||
|
}
|
||||||
|
public void Load(BinaryReader reader, UInt32 origin) {
|
||||||
|
reader.BaseStream.Position = origin + LangTagOffset;
|
||||||
|
Value = Encoding.BigEndianUnicode.GetString(reader.ReadBytes(Length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public sealed class MetaTable : FontTable<DataMap> {
|
||||||
|
readonly UInt32 version;
|
||||||
|
#pragma warning disable IDE0052 // Reserved
|
||||||
|
readonly UInt32 flags;
|
||||||
|
#pragma warning restore IDE0052 // Reserved
|
||||||
|
readonly UInt32 dataMapCount;
|
||||||
|
readonly List<DataMap> dataMaps = new List<DataMap>();
|
||||||
|
public MetaTable(BinaryReader reader, UInt32 offset) : base(reader, offset) {
|
||||||
|
version = reader.ReadUInt32();
|
||||||
|
if (version != 1) throw new NotSupportedException();
|
||||||
|
flags = reader.ReadUInt32();
|
||||||
|
reader.ReadUInt32();
|
||||||
|
dataMapCount = reader.ReadUInt32();
|
||||||
|
for (UInt32 i = 0; i < dataMapCount; i++)
|
||||||
|
dataMaps.Add(new DataMap (
|
||||||
|
reader.ReadTag(),
|
||||||
|
reader.ReadUInt32(),
|
||||||
|
reader.ReadUInt32()
|
||||||
|
));
|
||||||
|
foreach (var i in dataMaps)
|
||||||
|
i.Load(reader, offset);
|
||||||
|
}
|
||||||
|
public sealed override IReadOnlyList<DataMap> GetItems() {
|
||||||
|
return dataMaps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class DataMap {
|
||||||
|
public String Tag { get; private set; }
|
||||||
|
public UInt32 DataOffset { get; private set; }
|
||||||
|
public UInt32 DataLength { get; private set; }
|
||||||
|
public String Value { get; private set; }
|
||||||
|
public DataMap(String tag, UInt32 dataOffset, UInt32 dataLength) {
|
||||||
|
Tag = tag;
|
||||||
|
DataOffset = dataOffset;
|
||||||
|
DataLength = dataLength;
|
||||||
|
}
|
||||||
|
public void Load(BinaryReader reader, UInt32 origin) {
|
||||||
|
reader.BaseStream.Position = origin + DataOffset;
|
||||||
|
Value = Encoding.ASCII.GetString(reader.ReadBytes((int)DataLength));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static class BinaryReaderExtensions {
|
||||||
|
public static string ReadTag(this BinaryReader reader) {
|
||||||
|
return Encoding.ASCII.GetString(reader.ReadBytes(4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Cryville.Common/Font/FontTable.cs.meta
Normal file
11
Assets/Cryville.Common/Font/FontTable.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3805282a4858eec4d8ff91826ed7e896
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
31
Assets/Cryville.Common/Font/Typeface.cs
Normal file
31
Assets/Cryville.Common/Font/Typeface.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Cryville.Common.Font {
|
||||||
|
public abstract class Typeface {
|
||||||
|
public FileInfo File { get; private set; }
|
||||||
|
public int IndexInFile { get; private set; }
|
||||||
|
public string FamilyName { get; protected set; }
|
||||||
|
public string SubfamilyName { get; protected set; }
|
||||||
|
public string FullName { get; protected set; }
|
||||||
|
protected abstract void GetName(BinaryReader reader);
|
||||||
|
|
||||||
|
public Typeface(BinaryReader reader, FileInfo file, int index) {
|
||||||
|
File = file;
|
||||||
|
IndexInFile = index;
|
||||||
|
GetName(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class TypefaceTTF : Typeface {
|
||||||
|
public TypefaceTTF(BinaryReader reader, FileInfo file, int index)
|
||||||
|
: base(reader, file, index) { }
|
||||||
|
|
||||||
|
protected override void GetName(BinaryReader reader) {
|
||||||
|
var dir = new TableDirectory(reader, (uint)reader.BaseStream.Position);
|
||||||
|
var nameTable = (NameTable)dir.GetSubTable((from i in dir.GetItems() where i.tableTag == "name" select i).Single());
|
||||||
|
FamilyName = (from i in nameTable.GetItems() where i.NameID == NameID.FontFamilyName && i.Value != null select i.Value).First();
|
||||||
|
SubfamilyName = (from i in nameTable.GetItems() where i.NameID == NameID.FontSubfamilyName && i.Value != null select i.Value).First();
|
||||||
|
FullName = (from i in nameTable.GetItems() where i.NameID == NameID.FullFontName && i.Value != null select i.Value).First();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Cryville.Common/Font/Typeface.cs.meta
Normal file
11
Assets/Cryville.Common/Font/Typeface.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 943e0cf54256f2a479996d877b2b0e84
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Cryville.Common/IO.meta
Normal file
8
Assets/Cryville.Common/IO.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dbb2a81779b10f34489a8c83287d48bc
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
75
Assets/Cryville.Common/IO/BinaryReaderBE.cs
Normal file
75
Assets/Cryville.Common/IO/BinaryReaderBE.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Cryville.Common.IO {
|
||||||
|
public class BinaryReaderBE : BinaryReader {
|
||||||
|
readonly byte[] m_buffer = new byte[8];
|
||||||
|
|
||||||
|
public BinaryReaderBE(Stream input) : base(input) { }
|
||||||
|
|
||||||
|
public BinaryReaderBE(Stream input, Encoding encoding) : base(input, encoding) { }
|
||||||
|
|
||||||
|
public BinaryReaderBE(Stream input, Encoding encoding, bool leaveOpen) : base(input, encoding, leaveOpen) { }
|
||||||
|
|
||||||
|
public override short ReadInt16() {
|
||||||
|
FillBuffer(2);
|
||||||
|
return (short)(m_buffer[1] | (m_buffer[0] << 8));
|
||||||
|
}
|
||||||
|
public override ushort ReadUInt16() {
|
||||||
|
FillBuffer(2);
|
||||||
|
return (ushort)(m_buffer[1] | (m_buffer[0] << 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int ReadInt32() {
|
||||||
|
FillBuffer(4);
|
||||||
|
return m_buffer[3] | (m_buffer[2] << 8) | (m_buffer[1] << 16) | (m_buffer[0] << 24);
|
||||||
|
}
|
||||||
|
public override uint ReadUInt32() {
|
||||||
|
FillBuffer(4);
|
||||||
|
return (uint)(m_buffer[3] | (m_buffer[2] << 8) | (m_buffer[1] << 16) | (m_buffer[0] << 24));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long ReadInt64() {
|
||||||
|
FillBuffer(8);
|
||||||
|
uint num = (uint)(m_buffer[7] | (m_buffer[6] << 8) | (m_buffer[5] << 16) | (m_buffer[4] << 24));
|
||||||
|
uint num2 = (uint)(m_buffer[3] | (m_buffer[2] << 8) | (m_buffer[1] << 16) | (m_buffer[0] << 24));
|
||||||
|
return (long)(((ulong)num2 << 32) | num);
|
||||||
|
}
|
||||||
|
public override ulong ReadUInt64() {
|
||||||
|
FillBuffer(8);
|
||||||
|
uint num = (uint)(m_buffer[7] | (m_buffer[6] << 8) | (m_buffer[5] << 16) | (m_buffer[4] << 24));
|
||||||
|
uint num2 = (uint)(m_buffer[3] | (m_buffer[2] << 8) | (m_buffer[1] << 16) | (m_buffer[0] << 24));
|
||||||
|
return ((ulong)num2 << 32) | num;
|
||||||
|
}
|
||||||
|
protected new void FillBuffer(int numBytes) {
|
||||||
|
if (m_buffer != null && (numBytes < 0 || numBytes > m_buffer.Length)) {
|
||||||
|
throw new ArgumentOutOfRangeException("numBytes", "Requested numBytes is larger than the internal buffer size");
|
||||||
|
}
|
||||||
|
|
||||||
|
int num = 0, num2;
|
||||||
|
if (BaseStream == null) {
|
||||||
|
throw new IOException("File not open");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numBytes == 1) {
|
||||||
|
num2 = BaseStream.ReadByte();
|
||||||
|
if (num2 == -1) {
|
||||||
|
throw new EndOfStreamException("The end of the stream is reached before numBytes could be read");
|
||||||
|
}
|
||||||
|
m_buffer[0] = (byte)num2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
num2 = BaseStream.Read(m_buffer, num, numBytes - num);
|
||||||
|
if (num2 == 0) {
|
||||||
|
throw new EndOfStreamException("The end of the stream is reached before numBytes could be read");
|
||||||
|
}
|
||||||
|
|
||||||
|
num += num2;
|
||||||
|
}
|
||||||
|
while (num < numBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Cryville.Common/IO/BinaryReaderBE.cs.meta
Normal file
11
Assets/Cryville.Common/IO/BinaryReaderBE.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8eaf9874d914c1349aabbb884c54b2d7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Cryville.Common/Unity.meta
Normal file
8
Assets/Cryville.Common/Unity.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bf3461b95c913eb44b2f2e653bf5eb79
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Cryville.Common/Unity/UI.meta
Normal file
8
Assets/Cryville.Common/Unity/UI.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ad96c636bfa80024f8427b7755b56639
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
113
Assets/Cryville.Common/Unity/UI/AspectRatioLayoutElement.cs
Normal file
113
Assets/Cryville.Common/Unity/UI/AspectRatioLayoutElement.cs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace Cryville.Common.Unity.UI {
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="ILayoutElement" /> that takes the length of one axis to compute the preferred length of the other axis with respect to a aspect ratio.
|
||||||
|
/// </summary>
|
||||||
|
[AddComponentMenu("Layout/Aspect Ratio Layout Element")]
|
||||||
|
[ExecuteAlways]
|
||||||
|
public class AspectRatioLayoutElement : UIBehaviour, ILayoutElement {
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("The aspect ratio. Width divided by height.")]
|
||||||
|
private float m_aspectRatio = 1;
|
||||||
|
/// <summary>
|
||||||
|
/// The aspect ratio. Width divided by height.
|
||||||
|
/// </summary>
|
||||||
|
public float AspectRatio {
|
||||||
|
get { return m_aspectRatio; }
|
||||||
|
set { SetProperty(ref m_aspectRatio, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("Whether to compute the length of the y axis.")]
|
||||||
|
private bool m_isVertical = false;
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to compute the length of the y axis.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsVertical {
|
||||||
|
get { return m_isVertical; }
|
||||||
|
set { SetProperty(ref m_isVertical, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetProperty<T>(ref T prop, T value) {
|
||||||
|
if (Equals(prop, value)) return;
|
||||||
|
prop = value;
|
||||||
|
SetDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public float minWidth {
|
||||||
|
get {
|
||||||
|
return m_isVertical ? -1 : (transform as RectTransform).rect.height * m_aspectRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public float preferredWidth { get { return minWidth; } }
|
||||||
|
/// <inheritdoc />
|
||||||
|
public float flexibleWidth { get { return -1; } }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public float minHeight {
|
||||||
|
get {
|
||||||
|
return m_isVertical ? (transform as RectTransform).rect.width / m_aspectRatio : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <inheritdoc />
|
||||||
|
public float preferredHeight { get { return minHeight; } }
|
||||||
|
/// <inheritdoc />
|
||||||
|
public float flexibleHeight { get { return -1; } }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public int layoutPriority { get { return 1; } }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void CalculateLayoutInputHorizontal() { }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void CalculateLayoutInputVertical() { }
|
||||||
|
|
||||||
|
protected override void OnEnable() {
|
||||||
|
base.OnEnable();
|
||||||
|
SetDirty();
|
||||||
|
}
|
||||||
|
protected override void OnBeforeTransformParentChanged() {
|
||||||
|
base.OnBeforeTransformParentChanged();
|
||||||
|
SetDirty();
|
||||||
|
}
|
||||||
|
protected override void OnTransformParentChanged() {
|
||||||
|
base.OnTransformParentChanged();
|
||||||
|
SetDirty();
|
||||||
|
}
|
||||||
|
protected override void OnDidApplyAnimationProperties() {
|
||||||
|
base.OnDidApplyAnimationProperties();
|
||||||
|
SetDirty();
|
||||||
|
}
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
protected override void OnValidate() {
|
||||||
|
base.OnValidate();
|
||||||
|
SetDirty();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
protected override void OnDisable() {
|
||||||
|
SetDirty();
|
||||||
|
base.OnDisable();
|
||||||
|
}
|
||||||
|
protected override void OnRectTransformDimensionsChange() {
|
||||||
|
base.OnRectTransformDimensionsChange();
|
||||||
|
SetDirty();
|
||||||
|
}
|
||||||
|
bool _delayedSetDirty;
|
||||||
|
private void SetDirty() {
|
||||||
|
if (!IsActive()) return;
|
||||||
|
if (CanvasUpdateRegistry.IsRebuildingLayout()) _delayedSetDirty = true;
|
||||||
|
else LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform);
|
||||||
|
}
|
||||||
|
void Update() {
|
||||||
|
if (!_delayedSetDirty) return;
|
||||||
|
_delayedSetDirty = false;
|
||||||
|
LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 96276a3ffc8f32c4fbb7035a6fb28e74
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Cryville.Common.Unity.UI {
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="DockLayoutGroup" /> that sets the aspect ratio of the docking element.
|
||||||
|
/// </summary>
|
||||||
|
[AddComponentMenu("Layout/Dock Aspect Ratio Layout Group")]
|
||||||
|
public sealed class DockAspectRatioLayoutGroup : DockLayoutGroup {
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("The aspect ratio of the docking element.")]
|
||||||
|
private float m_dockAspectRatio = 1;
|
||||||
|
/// <summary>
|
||||||
|
/// The aspect ratio of the docking element.
|
||||||
|
/// </summary>
|
||||||
|
public float DockAspectRatio {
|
||||||
|
get { return m_dockAspectRatio; }
|
||||||
|
set { base.SetProperty(ref m_dockAspectRatio, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override float GetDockElementSize(Vector2 groupSize) {
|
||||||
|
return groupSize.y * m_dockAspectRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9023f24d2fe04fe45bf66a9d029591c1
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
136
Assets/Cryville.Common/Unity/UI/DockLayoutGroup.cs
Normal file
136
Assets/Cryville.Common/Unity/UI/DockLayoutGroup.cs
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace Cryville.Common.Unity.UI {
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="LayoutGroup" /> that docks its first child element to one side.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class DockLayoutGroup : LayoutGroup {
|
||||||
|
/// <summary>
|
||||||
|
/// The dock side.
|
||||||
|
/// </summary>
|
||||||
|
public enum Side {
|
||||||
|
/// <summary>
|
||||||
|
/// Top.
|
||||||
|
/// </summary>
|
||||||
|
Top = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Right.
|
||||||
|
/// </summary>
|
||||||
|
Right = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// Bottom.
|
||||||
|
/// </summary>
|
||||||
|
Bottom = 2,
|
||||||
|
/// <summary>
|
||||||
|
/// Left.
|
||||||
|
/// </summary>
|
||||||
|
Left = 3,
|
||||||
|
}
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("The docking side of the first child element.")]
|
||||||
|
private Side m_side;
|
||||||
|
/// <summary>
|
||||||
|
/// The docking side of the first child element.
|
||||||
|
/// </summary>
|
||||||
|
public Side DockSide {
|
||||||
|
get { return m_side; }
|
||||||
|
set { SetProperty(ref m_side, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("The slide index. The children slide along the cross axis.")]
|
||||||
|
private float m_slideIndex;
|
||||||
|
/// <summary>
|
||||||
|
/// The slide index. The children slide along the axis.
|
||||||
|
/// </summary>
|
||||||
|
public float SlideIndex {
|
||||||
|
get { return m_slideIndex; }
|
||||||
|
set { SetProperty(ref m_slideIndex, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public sealed override void CalculateLayoutInputHorizontal() { base.CalculateLayoutInputHorizontal(); CalcAlongAxis(0); }
|
||||||
|
/// <inheritdoc />
|
||||||
|
public sealed override void CalculateLayoutInputVertical() { CalcAlongAxis(1); }
|
||||||
|
/// <inheritdoc />
|
||||||
|
public sealed override void SetLayoutHorizontal() { SetChildrenAlongAxis(0); }
|
||||||
|
/// <inheritdoc />
|
||||||
|
public sealed override void SetLayoutVertical() { SetChildrenAlongAxis(1); }
|
||||||
|
|
||||||
|
private void CalcAlongAxis(int axis) {
|
||||||
|
int isHorizontal = (int)m_side & 1;
|
||||||
|
if ((isHorizontal ^ axis) == 1) {
|
||||||
|
SetLayoutInputForAxis(0, 0, 1, axis); // TODO
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float padding = isHorizontal == 0 ? m_Padding.horizontal : m_Padding.vertical;
|
||||||
|
float totalMin = 0, totalPreferred = 0, totalFlexible = 0;
|
||||||
|
for (int i = 0; i < rectChildren.Count; i++) {
|
||||||
|
GetChildSizes(rectChildren[i], axis, out float min, out float preferred, out float flexible);
|
||||||
|
if (min > totalMin) totalMin = min;
|
||||||
|
if (preferred > totalPreferred) totalPreferred = preferred;
|
||||||
|
if (flexible > totalFlexible) totalFlexible = flexible;
|
||||||
|
}
|
||||||
|
SetLayoutInputForAxis(totalMin + padding, totalPreferred + padding, totalFlexible, axis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void GetChildSizes(RectTransform child, int axis, out float min, out float preferred, out float flexible) {
|
||||||
|
min = LayoutUtility.GetMinSize(child, axis);
|
||||||
|
preferred = LayoutUtility.GetPreferredSize(child, axis);
|
||||||
|
flexible = LayoutUtility.GetFlexibleSize(child, axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float GetSlidePosition(float groupHeight, float dockHeight) {
|
||||||
|
bool d = Mathf.FloorToInt(m_slideIndex - Mathf.Floor(m_slideIndex / 2) * 2) == 0;
|
||||||
|
int l = Mathf.FloorToInt(m_slideIndex / 2);
|
||||||
|
float p = m_slideIndex - Mathf.Floor(m_slideIndex);
|
||||||
|
if (d) return l * groupHeight + p * dockHeight;
|
||||||
|
else return l * groupHeight + dockHeight + p * (groupHeight - dockHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetChildrenAlongAxis(int axis) {
|
||||||
|
int isHorizontal = (int)m_side & 1;
|
||||||
|
bool isReversed = m_side == Side.Right || m_side == Side.Bottom;
|
||||||
|
var rect = rectTransform.rect;
|
||||||
|
if ((isHorizontal ^ axis) == 1) {
|
||||||
|
float p0 = isHorizontal == 1 ? m_Padding.left : m_Padding.top;
|
||||||
|
float p1 = isHorizontal == 1 ? m_Padding.right : m_Padding.bottom;
|
||||||
|
var gs = rect.size - new Vector2(m_Padding.horizontal, m_Padding.vertical);
|
||||||
|
if (isHorizontal == 0) gs = new Vector2(gs.y, gs.x);
|
||||||
|
if (rectChildren.Count == 1) {
|
||||||
|
SetChildAlongAxis(rectChildren[0], axis, p0, gs.x);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float s1 = GetDockElementSize(gs);
|
||||||
|
float s0 = GetSlidePosition(gs.x, s1);
|
||||||
|
float a1 = (isHorizontal == 0 ? rect.height : rect.width) - p0 - p1;
|
||||||
|
for (int i = 0; i < rectChildren.Count; i++) {
|
||||||
|
var c = rectChildren[i];
|
||||||
|
bool d = i % 2 == 0;
|
||||||
|
int l = i / 2;
|
||||||
|
if (isReversed)
|
||||||
|
SetChildAlongAxis(c, axis, (d ? a1 - s1 + p0 : p0) - a1 * l + s0, d ? s1 : a1 - s1);
|
||||||
|
else
|
||||||
|
SetChildAlongAxis(c, axis, (d ? p0 : s1 + p0) - s0 + a1 * l, d ? s1 : a1 - s1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float p0 = isHorizontal == 0 ? m_Padding.left : m_Padding.top;
|
||||||
|
float p1 = isHorizontal == 0 ? m_Padding.right : m_Padding.bottom;
|
||||||
|
var height = (isHorizontal == 1 ? rect.height : rect.width) - p0 - p1;
|
||||||
|
for (int i = 0; i < rectChildren.Count; i++) {
|
||||||
|
SetChildAlongAxis(rectChildren[i], axis, p0, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the length of the first child element along the axis.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="groupSize">The size of the layout group.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected abstract float GetDockElementSize(Vector2 groupSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Cryville.Common/Unity/UI/DockLayoutGroup.cs.meta
Normal file
11
Assets/Cryville.Common/Unity/UI/DockLayoutGroup.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fb94861327965934cb429511060d45fb
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Cryville.Common.Unity.UI {
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="DockLayoutGroup" /> that sets the occupied ratio of the docking element.
|
||||||
|
/// </summary>
|
||||||
|
[AddComponentMenu("Layout/Dock Occupied Ratio Layout Group")]
|
||||||
|
public sealed class DockOccupiedRatioLayoutGroup : DockLayoutGroup {
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("The occupied ratio of the docking element.")]
|
||||||
|
private float m_dockOccupiedRatio = 1;
|
||||||
|
/// <summary>
|
||||||
|
/// The occupied ratio of the docking element.
|
||||||
|
/// </summary>
|
||||||
|
public float DockOccupiedRatio {
|
||||||
|
get { return m_dockOccupiedRatio; }
|
||||||
|
set { base.SetProperty(ref m_dockOccupiedRatio, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override float GetDockElementSize(Vector2 groupSize) {
|
||||||
|
return groupSize.x * m_dockOccupiedRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0bbf3330df0a07e46bcdf0b3c4879ecf
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user