changhong/wb_unity_pro/Assets/Modules/FairyGUI/Scripts/UI/UIPackage.cs

1133 lines
30 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using FairyGUI.Utils;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace FairyGUI
{
/// <summary>
/// A UI Package contains a description file and some texture,sound assets.
/// </summary>
public class UIPackage
{
/// <summary>
/// Package id. It is generated by the Editor, or set by customId.
/// </summary>
public string id { get; private set; }
/// <summary>
/// Package name.
/// </summary>
public string name { get; private set; }
/// <summary>
/// The path relative to the resources folder.
/// </summary>
public string assetPath { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="result"></param>
public delegate void CreateObjectCallback(GObject result);
List<PackageItem> _items;
Dictionary<string, PackageItem> _itemsById;
Dictionary<string, PackageItem> _itemsByName;
string _customId;
bool _resourceMode;
class AtlasSprite
{
public PackageItem atlas;
public Rect rect = new Rect();
public bool rotated;
}
Dictionary<string, AtlasSprite> _sprites;
static Dictionary<string, UIPackage> _packageInstById = new Dictionary<string, UIPackage>();
static Dictionary<string, UIPackage> _packageInstByName = new Dictionary<string, UIPackage>();
static List<UIPackage> _packageList = new List<UIPackage>();
internal static int _constructing;
public const string URL_PREFIX = "ui://";
#if UNITY_EDITOR && !PACK
List<string> _assetMap = new List<string>();
#endif
public UIPackage()
{
_items = new List<PackageItem>();
_itemsById = new Dictionary<string, PackageItem>();
_itemsByName = new Dictionary<string, PackageItem>();
_sprites = new Dictionary<string, AtlasSprite>();
}
/// <summary>
/// Return a UIPackage with a certain id.
/// </summary>
/// <param name="id">ID of the package.</param>
/// <returns>UIPackage</returns>
public static UIPackage GetById(string id)
{
UIPackage pkg;
if (_packageInstById.TryGetValue(id, out pkg))
return pkg;
else
return null;
}
/// <summary>
/// Return a UIPackage with a certain name.
/// </summary>
/// <param name="name">Name of the package.</param>
/// <returns>UIPackage</returns>
public static UIPackage GetByName(string name)
{
UIPackage pkg;
if (_packageInstByName.TryGetValue(name, out pkg))
return pkg;
else
return null;
}
UnityEngine.Object _loadFunc(string name, string extension, System.Type type, out DestroyMethod destroyMethod)
{
destroyMethod = DestroyMethod.Unload;
UnityEngine.Object obj = null;
var path = name + extension;
if (_resourceMode)
{
obj = Resources.Load(name, type);
}
else
{
obj = taurus.unity.ResourcesManager.LoadObject(path, type);
if (obj == null)
{
obj = Resources.Load(name, type);
}
}
#if UNITY_EDITOR && !PACK
if (obj != null)
{
_assetMap.Add(path);
}
#endif
return obj;
}
/// <summary>
/// Add a UI package from a path relative to Unity Resources path.
/// </summary>
/// <param name="descFilePath">Path relative to Unity Resources path.</param>
/// <returns>UIPackage</returns>
public static UIPackage AddPackage(string descFilePath)
{
return AddPackage(descFilePath, false);
}
/// <summary>
/// 使用自定义的加载方式载入一个包。
/// </summary>
/// <param name="assetPath">包资源路径。</param>
/// <param name="loadFunc">载入函数</param>
/// <returns></returns>
public static UIPackage AddPackage(string assetPath, bool _resourceMode)
{
if (_packageInstById.ContainsKey(assetPath))
return _packageInstById[assetPath];
DestroyMethod dm;
UIPackage pkg = new UIPackage();
pkg._resourceMode = _resourceMode;
TextAsset asset = (TextAsset)pkg._loadFunc(assetPath + "_fui", ".bytes", typeof(TextAsset), out dm);
if (asset == null)
{
if (Application.isPlaying)
throw new Exception("FairyGUI: Cannot load ui package in '" + assetPath + "'");
else
Debug.LogWarning("FairyGUI: Cannot load ui package in '" + assetPath + "'");
}
ByteBuffer buffer = new ByteBuffer(asset.bytes);
pkg.assetPath = assetPath;
if (!pkg.LoadPackage(buffer, assetPath, assetPath))
return null;
_packageInstById[pkg.id] = pkg;
_packageInstByName[pkg.name] = pkg;
_packageInstById[assetPath] = pkg;
_packageList.Add(pkg);
return pkg;
}
/// <summary>
/// Remove a package. All resources in this package will be disposed.
/// </summary>
/// <param name="packageIdOrName"></param>
/// <param name="allowDestroyingAssets"></param>
public static void RemovePackage(string packageIdOrName)
{
UIPackage pkg = null;
if (!_packageInstById.TryGetValue(packageIdOrName, out pkg))
{
if (!_packageInstByName.TryGetValue(packageIdOrName, out pkg))
{
//Debugger.LogError("FairyGUI: '" + packageIdOrName + "' is not a valid package id or name.");
return;
}
}
pkg.Dispose();
#if UNITY_EDITOR && !PACK
foreach (string path in pkg._assetMap)
{
taurus.unity.ResourcesManager.UnLoad(path);
}
pkg._assetMap.Clear();
#else
taurus.unity.ResourcesManager.UnLoad(packageIdOrName + "_fui.bytes");
#endif
_packageInstById.Remove(pkg.id);
if (pkg._customId != null)
_packageInstById.Remove(pkg._customId);
if (pkg.assetPath != null)
_packageInstById.Remove(pkg.assetPath);
_packageInstByName.Remove(pkg.name);
_packageList.Remove(pkg);
}
/// <summary>
///
/// </summary>
public static void RemoveAllPackages()
{
if (_packageInstById.Count > 0)
{
UIPackage[] pkgs = _packageList.ToArray();
foreach (UIPackage pkg in pkgs)
{
pkg.Dispose();
}
}
_packageList.Clear();
_packageInstById.Clear();
_packageInstByName.Clear();
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static List<UIPackage> GetPackages()
{
return _packageList;
}
/// <summary>
/// Create a UI object.
/// </summary>
/// <param name="pkgName">Package name.</param>
/// <param name="resName">Resource name.</param>
/// <returns>A UI object.</returns>
public static GObject CreateObject(string pkgName, string resName)
{
UIPackage pkg = GetByName(pkgName);
if (pkg != null)
return pkg.CreateObject(resName);
else
return null;
}
/// <summary>
/// Create a UI object.
/// </summary>
/// <param name="pkgName">Package name.</param>
/// <param name="resName">Resource name.</param>
/// <param name="userClass">Custom implementation of this object.</param>
/// <returns>A UI object.</returns>
public static GObject CreateObject(string pkgName, string resName, System.Type userClass)
{
UIPackage pkg = GetByName(pkgName);
if (pkg != null)
return pkg.CreateObject(resName, userClass);
else
return null;
}
/// <summary>
/// Create a UI object.
/// </summary>
/// <param name="url">Resource url.</param>
/// <returns>A UI object.</returns>
public static GObject CreateObjectFromURL(string url)
{
PackageItem pi = GetItemByURL(url);
if (pi != null)
return pi.owner.CreateObject(pi, null);
else
return null;
}
/// <summary>
/// Create a UI object.
/// </summary>
/// <param name="url">Resource url.</param>
/// <param name="userClass">Custom implementation of this object.</param>
/// <returns>A UI object.</returns>
public static GObject CreateObjectFromURL(string url, System.Type userClass)
{
PackageItem pi = GetItemByURL(url);
if (pi != null)
return pi.owner.CreateObject(pi, userClass);
else
return null;
}
public static void CreateObjectAsync(string pkgName, string resName, CreateObjectCallback callback)
{
UIPackage pkg = GetByName(pkgName);
if (pkg != null)
pkg.CreateObjectAsync(resName, callback);
else
Debug.LogError("FairyGUI: package not found - " + pkgName);
}
public static void CreateObjectFromURL(string url, CreateObjectCallback callback)
{
PackageItem pi = GetItemByURL(url);
if (pi != null)
AsyncCreationHelper.CreateObject(pi, callback);
else
Debug.LogError("FairyGUI: resource not found - " + url);
}
/// <summary>
/// Get a asset with a certain name.
/// </summary>
/// <param name="pkgName">Package name.</param>
/// <param name="resName">Resource name.</param>
/// <returns>If resource is atlas, returns NTexture; If resource is sound, returns AudioClip.</returns>
public static object GetItemAsset(string pkgName, string resName)
{
UIPackage pkg = GetByName(pkgName);
if (pkg != null)
return pkg.GetItemAsset(resName);
else
return null;
}
/// <summary>
/// Get a asset with a certain name.
/// </summary>
/// <param name="url">Resource url.</param>
/// <returns>If resource is atlas, returns NTexture; If resource is sound, returns AudioClip.</returns>
public static object GetItemAssetByURL(string url)
{
PackageItem item = GetItemByURL(url);
if (item == null)
return null;
return item.owner.GetItemAsset(item);
}
/// <summary>
/// Get url of an item in package.
/// </summary>
/// <param name="pkgName">Package name.</param>
/// <param name="resName">Resource name.</param>
/// <returns>Url.</returns>
public static string GetItemURL(string pkgName, string resName)
{
UIPackage pkg = GetByName(pkgName);
if (pkg == null)
return null;
PackageItem pi;
if (!pkg._itemsByName.TryGetValue(resName, out pi))
return null;
return URL_PREFIX + pkg.id + pi.id;
}
public static PackageItem GetItemByURL(string url)
{
if (url == null)
return null;
int pos1 = url.IndexOf("//");
if (pos1 == -1)
return null;
int pos2 = url.IndexOf('/', pos1 + 2);
if (pos2 == -1)
{
if (url.Length > 13)
{
string pkgId = url.Substring(5, 8);
UIPackage pkg = GetById(pkgId);
if (pkg != null)
{
string srcId = url.Substring(13);
return pkg.GetItem(srcId);
}
}
}
else
{
string pkgName = url.Substring(pos1 + 2, pos2 - pos1 - 2);
UIPackage pkg = GetByName(pkgName);
if (pkg != null)
{
string srcName = url.Substring(pos2 + 1);
return pkg.GetItemByName(srcName);
}
}
return null;
}
/// <summary>
/// 将'ui://包名/组件名'转换为以内部id表达的url格式。如果传入的url本身就是内部id格式则直接返回。
/// 同时这个方法还带格式检测如果传入不正确的url会返回null。
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string NormalizeURL(string url)
{
if (url == null)
return null;
int pos1 = url.IndexOf("//");
if (pos1 == -1)
return null;
int pos2 = url.IndexOf('/', pos1 + 2);
if (pos2 == -1)
return url;
else
{
string pkgName = url.Substring(pos1 + 2, pos2 - pos1 - 2);
string srcName = url.Substring(pos2 + 1);
return GetItemURL(pkgName, srcName);
}
}
/// <summary>
/// Set strings source.
/// </summary>
/// <param name="source"></param>
public static void SetStringsSource(XML source)
{
TranslationHelper.LoadFromXML(source);
}
/// <summary>
/// Set a custom id for package, then you can use it in GetById.
/// </summary>
public string customId
{
get { return _customId; }
set
{
if (_customId != null)
_packageInstById.Remove(_customId);
_customId = value;
if (_customId != null)
_packageInstById[_customId] = this;
}
}
bool LoadPackage(ByteBuffer buffer, string packageSource, string assetNamePrefix)
{
if (buffer.ReadUint() != 0x46475549)
{
if (Application.isPlaying)
throw new Exception("FairyGUI: old package format found in '" + packageSource + "'");
else
{
Debug.LogWarning("FairyGUI: old package format found in '" + packageSource + "'");
return false;
}
}
buffer.version = buffer.ReadInt();
buffer.ReadBool(); //compressed
id = buffer.ReadString();
name = buffer.ReadString();
if (_packageInstById.ContainsKey(id) && name != _packageInstById[id].name)
{
throw new Exception("FairyGUI: Package id conflicts, '" + name + "' and '" + _packageInstById[id].name + "'");
}
buffer.Skip(20);
int indexTablePos = buffer.position;
int cnt;
buffer.Seek(indexTablePos, 4);
cnt = buffer.ReadInt();
string[] stringTable = new string[cnt];
for (int i = 0; i < cnt; i++)
stringTable[i] = buffer.ReadString();
buffer.stringTable = stringTable;
buffer.Seek(indexTablePos, 1);
PackageItem pi;
if (assetNamePrefix == null)
assetNamePrefix = string.Empty;
else if (assetNamePrefix.Length > 0)
assetNamePrefix = assetNamePrefix + "_";
cnt = buffer.ReadShort();
for (int i = 0; i < cnt; i++)
{
int nextPos = buffer.ReadInt();
nextPos += buffer.position;
pi = new PackageItem();
pi.owner = this;
pi.type = (PackageItemType)buffer.ReadByte();
pi.id = buffer.ReadS();
pi.name = buffer.ReadS();
buffer.ReadS(); //path
pi.file = buffer.ReadS();
pi.exported = buffer.ReadBool();
pi.width = buffer.ReadInt();
pi.height = buffer.ReadInt();
switch (pi.type)
{
case PackageItemType.Image:
{
pi.objectType = ObjectType.Image;
int scaleOption = buffer.ReadByte();
if (scaleOption == 1)
{
Rect rect = new Rect();
rect.x = buffer.ReadInt();
rect.y = buffer.ReadInt();
rect.width = buffer.ReadInt();
rect.height = buffer.ReadInt();
pi.scale9Grid = rect;
pi.tileGridIndice = buffer.ReadInt();
}
else if (scaleOption == 2)
pi.scaleByTile = true;
buffer.ReadBool(); //smoothing
break;
}
case PackageItemType.MovieClip:
{
buffer.ReadBool(); //smoothing
pi.objectType = ObjectType.MovieClip;
pi.rawData = buffer.ReadBuffer();
break;
}
case PackageItemType.Font:
{
pi.rawData = buffer.ReadBuffer();
break;
}
case PackageItemType.Component:
{
int extension = buffer.ReadByte();
if (extension > 0)
pi.objectType = (ObjectType)extension;
else
pi.objectType = ObjectType.Component;
pi.rawData = buffer.ReadBuffer();
UIObjectFactory.ResolvePackageItemExtension(pi);
break;
}
case PackageItemType.Atlas:
case PackageItemType.Sound:
case PackageItemType.Misc:
{
pi.file = assetNamePrefix + pi.file;
break;
}
}
_items.Add(pi);
_itemsById[pi.id] = pi;
if (pi.name != null)
_itemsByName[pi.name] = pi;
buffer.position = nextPos;
}
buffer.Seek(indexTablePos, 2);
cnt = buffer.ReadShort();
for (int i = 0; i < cnt; i++)
{
int nextPos = buffer.ReadShort();
nextPos += buffer.position;
string itemId = buffer.ReadS();
pi = _itemsById[buffer.ReadS()];
AtlasSprite sprite = new AtlasSprite();
sprite.atlas = pi;
sprite.rect.x = buffer.ReadInt();
sprite.rect.y = buffer.ReadInt();
sprite.rect.width = buffer.ReadInt();
sprite.rect.height = buffer.ReadInt();
sprite.rotated = buffer.ReadBool();
_sprites[itemId] = sprite;
buffer.position = nextPos;
}
if (buffer.Seek(indexTablePos, 3))
{
cnt = buffer.ReadShort();
for (int i = 0; i < cnt; i++)
{
int nextPos = buffer.ReadInt();
nextPos += buffer.position;
if (_itemsById.TryGetValue(buffer.ReadS(), out pi))
{
if (pi.type == PackageItemType.Image)
{
pi.pixelHitTestData = new PixelHitTestData();
pi.pixelHitTestData.Load(buffer);
}
}
buffer.position = nextPos;
}
}
if (!Application.isPlaying)
_items.Sort(ComparePackageItem);
return true;
}
static int ComparePackageItem(PackageItem p1, PackageItem p2)
{
if (p1.name != null && p2.name != null)
return p1.name.CompareTo(p2.name);
else
return 0;
}
/// <summary>
///
/// </summary>
public void LoadAllAssets()
{
int cnt = _items.Count;
for (int i = 0; i < cnt; i++)
GetItemAsset(_items[i]);
}
/// <summary>
///
/// </summary>
public void UnloadAssets()
{
int cnt = _items.Count;
for (int i = 0; i < cnt; i++)
{
PackageItem pi = _items[i];
if (pi.type == PackageItemType.Atlas)
{
if (pi.texture != null)
pi.texture.Unload();
}
else if (pi.type == PackageItemType.Sound)
{
if (pi.audioClip != null)
pi.audioClip.Unload();
}
}
}
/// <summary>
///
/// </summary>
public void ReloadAssets()
{
int cnt = _items.Count;
for (int i = 0; i < cnt; i++)
{
PackageItem pi = _items[i];
if (pi.type == PackageItemType.Atlas)
{
if (pi.texture != null && pi.texture.nativeTexture == null)
LoadAtlas(pi);
}
else if (pi.type == PackageItemType.Sound)
{
if (pi.audioClip != null && pi.audioClip.nativeClip == null)
LoadSound(pi);
}
}
}
void Dispose()
{
int cnt = _items.Count;
for (int i = 0; i < cnt; i++)
{
PackageItem pi = _items[i];
if (pi.type == PackageItemType.Atlas)
{
if (pi.texture != null)
{
pi.texture.Dispose();
pi.texture = null;
}
}
else if (pi.type == PackageItemType.Sound)
{
if (pi.audioClip != null)
{
pi.audioClip.Unload();
pi.audioClip = null;
}
}
}
_items.Clear();
}
/// <summary>
///
/// </summary>
/// <param name="resName"></param>
/// <returns></returns>
public GObject CreateObject(string resName)
{
PackageItem pi;
if (!_itemsByName.TryGetValue(resName, out pi))
{
Debug.LogError("FairyGUI: resource not found - " + resName + " in " + this.name);
return null;
}
return CreateObject(pi, null);
}
/// <summary>
///
/// </summary>
/// <param name="resName"></param>
/// <param name="userClass"></param>
/// <returns></returns>
public GObject CreateObject(string resName, System.Type userClass)
{
PackageItem pi;
if (!_itemsByName.TryGetValue(resName, out pi))
{
Debug.LogError("FairyGUI: resource not found - " + resName + " in " + this.name);
return null;
}
return CreateObject(pi, userClass);
}
public void CreateObjectAsync(string resName, CreateObjectCallback callback)
{
PackageItem pi;
if (!_itemsByName.TryGetValue(resName, out pi))
{
Debug.LogError("FairyGUI: resource not found - " + resName + " in " + this.name);
return;
}
AsyncCreationHelper.CreateObject(pi, callback);
}
GObject CreateObject(PackageItem item, System.Type userClass)
{
Stats.LatestObjectCreation = 0;
Stats.LatestGraphicsCreation = 0;
GetItemAsset(item);
GObject g = null;
if (item.type == PackageItemType.Component)
{
if (userClass != null)
g = (GComponent)Activator.CreateInstance(userClass);
else
g = UIObjectFactory.NewObject(item);
}
else
g = UIObjectFactory.NewObject(item);
if (g == null)
return null;
_constructing++;
g.packageItem = item;
g.ConstructFromResource();
_constructing--;
return g;
}
/// <summary>
///
/// </summary>
/// <param name="resName"></param>
/// <returns></returns>
public object GetItemAsset(string resName)
{
PackageItem pi;
if (!_itemsByName.TryGetValue(resName, out pi))
{
Debug.LogError("FairyGUI: Resource not found - " + resName + " in " + this.name);
return null;
}
return GetItemAsset(pi);
}
public List<PackageItem> GetItems()
{
return _items;
}
public PackageItem GetItem(string itemId)
{
PackageItem pi;
if (_itemsById.TryGetValue(itemId, out pi))
return pi;
else
return null;
}
public PackageItem GetItemByName(string itemName)
{
PackageItem pi;
if (_itemsByName.TryGetValue(itemName, out pi))
return pi;
else
return null;
}
public object GetItemAsset(PackageItem item)
{
switch (item.type)
{
case PackageItemType.Image:
if (item.texture == null)
LoadImage(item);
return item.texture;
case PackageItemType.Atlas:
if (item.texture == null)
LoadAtlas(item);
return item.texture;
case PackageItemType.Sound:
if (item.audioClip == null)
LoadSound(item);
return item.audioClip;
case PackageItemType.Font:
if (item.bitmapFont == null)
LoadFont(item);
return item.bitmapFont;
case PackageItemType.MovieClip:
if (item.frames == null)
LoadMovieClip(item);
return item.frames;
case PackageItemType.Component:
return item.rawData;
case PackageItemType.Misc:
return LoadBinary(item);
default:
return null;
}
}
void LoadAtlas(PackageItem item)
{
string ext = Path.GetExtension(item.file);
string fileName = item.file.Substring(0, item.file.Length - ext.Length);
Texture tex = null;
Texture alphaTex = null;
DestroyMethod dm;
tex = (Texture)_loadFunc(fileName, ext, typeof(Texture), out dm);
if (tex == null)
Debug.LogWarning("FairyGUI: texture '" + item.file + "' not found in " + this.name);
else if (!(tex is Texture2D))
{
Debug.LogWarning("FairyGUI: settings for '" + item.file + "' is wrong! Correct values are: (Texture Type=Default, Texture Shape=2D)");
tex = null;
}
else
{
if (((Texture2D)tex).mipmapCount > 1)
Debug.LogWarning("FairyGUI: settings for '" + item.file + "' is wrong! Correct values are: (Generate Mip Maps=unchecked)");
}
if (tex != null)
{
fileName = fileName + "!a";
alphaTex = (Texture2D)_loadFunc(fileName, ext, typeof(Texture2D), out dm);
}
if (tex == null)
{
tex = NTexture.CreateEmptyTexture();
dm = DestroyMethod.Destroy;
}
if (item.texture == null)
{
item.texture = new NTexture(tex, alphaTex, (float)tex.width / item.width, (float)tex.height / item.height);
item.texture.destroyMethod = dm;
}
else
{
item.texture.Reload(tex, alphaTex);
item.texture.destroyMethod = dm;
}
}
void LoadImage(PackageItem item)
{
AtlasSprite sprite;
if (_sprites.TryGetValue(item.id, out sprite))
item.texture = new NTexture((NTexture)GetItemAsset(sprite.atlas), sprite.rect, sprite.rotated);
else
item.texture = NTexture.Empty;
}
void LoadSound(PackageItem item)
{
string ext = Path.GetExtension(item.file);
string fileName = item.file.Substring(0, item.file.Length - ext.Length);
AudioClip audioClip = null;
DestroyMethod dm;
audioClip = (AudioClip)_loadFunc(fileName, ext, typeof(AudioClip), out dm);
if (item.audioClip == null)
item.audioClip = new NAudioClip(audioClip);
else
item.audioClip.Reload(audioClip);
item.audioClip.destroyMethod = dm;
}
byte[] LoadBinary(PackageItem item)
{
string ext = Path.GetExtension(item.file);
string fileName = item.file.Substring(0, item.file.Length - ext.Length);
DestroyMethod dm;
object ret = _loadFunc(fileName, ext, typeof(TextAsset), out dm);
if (ret == null)
return null;
if (ret is byte[])
return (byte[])ret;
else
return ((TextAsset)ret).bytes;
}
void LoadMovieClip(PackageItem item)
{
ByteBuffer buffer = item.rawData;
buffer.Seek(0, 0);
item.interval = buffer.ReadInt() / 1000f;
item.swing = buffer.ReadBool();
item.repeatDelay = buffer.ReadInt() / 1000f;
buffer.Seek(0, 1);
int frameCount = buffer.ReadShort();
item.frames = new MovieClip.Frame[frameCount];
string spriteId;
MovieClip.Frame frame;
AtlasSprite sprite;
Rect frameRect = new Rect();
for (int i = 0; i < frameCount; i++)
{
int nextPos = buffer.ReadShort();
nextPos += buffer.position;
frame = new MovieClip.Frame();
frameRect.x = buffer.ReadInt();
frameRect.y = buffer.ReadInt();
frameRect.width = buffer.ReadInt();
frameRect.height = buffer.ReadInt();
frame.addDelay = buffer.ReadInt() / 1000f;
spriteId = buffer.ReadS();
if (spriteId != null && _sprites.TryGetValue(spriteId, out sprite))
{
frame.texture = new NTexture((NTexture)GetItemAsset(sprite.atlas), sprite.rect, sprite.rotated,
new Vector2(item.width, item.height), frameRect.position);
}
item.frames[i] = frame;
buffer.position = nextPos;
}
}
void LoadFont(PackageItem item)
{
BitmapFont font = new BitmapFont(item);
item.bitmapFont = font;
ByteBuffer buffer = item.rawData;
buffer.Seek(0, 0);
bool ttf = buffer.ReadBool();
font.canTint = buffer.ReadBool();
font.resizable = buffer.ReadBool();
font.hasChannel = buffer.ReadBool();
int fontSize = buffer.ReadInt();
int xadvance = buffer.ReadInt();
int lineHeight = buffer.ReadInt();
float texScaleX = 1;
float texScaleY = 1;
NTexture mainTexture = null;
AtlasSprite mainSprite = null;
if (ttf && _sprites.TryGetValue(item.id, out mainSprite))
{
mainTexture = (NTexture)GetItemAsset(mainSprite.atlas);
texScaleX = mainTexture.root.uvRect.width / mainTexture.width;
texScaleY = mainTexture.root.uvRect.height / mainTexture.height;
}
buffer.Seek(0, 1);
BitmapFont.BMGlyph bg;
int cnt = buffer.ReadInt();
for (int i = 0; i < cnt; i++)
{
int nextPos = buffer.ReadShort();
nextPos += buffer.position;
bg = new BitmapFont.BMGlyph();
char ch = buffer.ReadChar();
font.AddChar(ch, bg);
string img = buffer.ReadS();
int bx = buffer.ReadInt();
int by = buffer.ReadInt();
bg.offsetX = buffer.ReadInt();
bg.offsetY = buffer.ReadInt();
bg.width = buffer.ReadInt();
bg.height = buffer.ReadInt();
bg.advance = buffer.ReadInt();
bg.channel = buffer.ReadByte();
//The texture channel where the character image is found (1 = blue, 2 = green, 4 = red, 8 = alpha).
if (bg.channel == 1)
bg.channel = 2;
else if (bg.channel == 2)
bg.channel = 1;
else if (bg.channel == 3)
bg.channel = 0;
else if (bg.channel == 8)
bg.channel = 3;
if (ttf)
{
if (mainSprite.rotated)
{
bg.uv[0] = new Vector2((float)(by + bg.height + mainSprite.rect.x) * texScaleX,
1 - (float)(mainSprite.rect.yMax - bx) * texScaleY);
bg.uv[1] = new Vector2(bg.uv[0].x - (float)bg.height * texScaleX, bg.uv[0].y);
bg.uv[2] = new Vector2(bg.uv[1].x, bg.uv[0].y + (float)bg.width * texScaleY);
bg.uv[3] = new Vector2(bg.uv[0].x, bg.uv[2].y);
}
else
{
bg.uv[0] = new Vector2((float)(bx + mainSprite.rect.x) * texScaleX,
1 - (float)(by + bg.height + mainSprite.rect.y) * texScaleY);
bg.uv[1] = new Vector2(bg.uv[0].x, bg.uv[0].y + (float)bg.height * texScaleY);
bg.uv[2] = new Vector2(bg.uv[0].x + (float)bg.width * texScaleX, bg.uv[1].y);
bg.uv[3] = new Vector2(bg.uv[2].x, bg.uv[0].y);
}
bg.lineHeight = lineHeight;
}
else
{
PackageItem charImg;
if (_itemsById.TryGetValue(img, out charImg))
{
GetItemAsset(charImg);
charImg.texture.GetUV(bg.uv);
bg.width = charImg.texture.width;
bg.height = charImg.texture.height;
if (mainTexture == null)
mainTexture = charImg.texture.root;
}
if (fontSize == 0)
fontSize = bg.height;
if (bg.advance == 0)
{
if (xadvance == 0)
bg.advance = bg.offsetX + bg.width;
else
bg.advance = xadvance;
}
bg.lineHeight = bg.offsetY < 0 ? bg.height : (bg.offsetY + bg.height);
if (bg.lineHeight < font.size)
bg.lineHeight = font.size;
}
buffer.position = nextPos;
}
font.size = fontSize;
font.mainTexture = mainTexture;
if (!font.hasChannel)
font.shader = ShaderConfig.imageShader;
}
}
}