爲什麼要自己寫圖文混排?
NGUI的UIlabel本身支持圖文混排,只不過只支持位圖字體,侷限性很強,所以在具體項目中很難滿足需求。
自己寫的話,有什麼想法?
圖文混排的基礎功能無非:圖片或紋理和文字的混合排列,點擊行爲、超鏈接、動態支持字號,字色,描邊等功能。
之前倒是接觸過前輩們寫的自定義插件,雖說基本夠用但也存在各種問題,結構複雜,排序算法純屬邏輯堆積,維護複雜。
結構設計?
基本思路:使用stringTag解析數據結構,生成數據隊列。
使用OO:圖文混排中的任何文本,圖像,抽象爲單個Unit對象,定義一個基礎Unit類,包含組件類型,內容記錄等屬性,其他組件繼承基礎組件,並在子類中自定義自己的個性方法,不同子類在構造函數中根據傳入數據,解析自身屬性。並且摒棄邏輯堆疊的排序算法,子類根據傳入數據自己處理組件實現自己的排序算法,除此之外,實現點擊行爲,組件設置等定製行爲。
其他需求:行對其方式(上部對其,中間對其,下部對其),RichUnit工廠,根據外部數據構造源串數據,邊緣裁切算法。
基類及其子類:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum ContentType
{
none = 0, //無
test = 1, //純文本
testCanClick = 2, //純文本可點擊
icon = 3, //圖片
iconCanClick = 4, //圖片可點擊
texture = 5, //紋理
textureCanClick = 6,//紋理可點擊
newLine = 7, //換行
}
public class RichContentUnit {
//Unit類型
public ContentType type;
//傳入的源文本
public string sourceContent;
//回傳數據
public string messageContent;
public bool init = false;
//父管理組件
public NGUIRichContentLabel parent;
//根據當前行高-調整元素位置
public void AdjustAllLine(List<UIWidget> currentLine, int maxHeight, float standardY)
{
float newPos = 0f;
for (int i = 0; i < currentLine.Count; i++)
{
if (currentLine [i].height < maxHeight)
{
Vector3 widgetPos = currentLine [i].transform.localPosition;
newPos = standardY + currentLine [i].height / 2f - maxHeight / 2f;
if (Mathf.Abs (newPos - widgetPos.y) > 0.001f)//判定爲位置需要調整
{
currentLine [i].transform.localPosition = new Vector3(widgetPos.x,newPos,0);
}
}
}
}
}
public class RichLabel : RichContentUnit
{
public int FontSize;
public string fontColor;
public string OutLineColor;
public string content;
public List<UILabel> labels;
public RichLabel(ContentType unitType,string content,NGUIRichContentLabel instance)
{
type = unitType;
content = content.Replace ("\n",string.Empty);
//文本@字號@字體顏色@描邊顏色@message(點擊時回傳)
string[] splitStr = content.Split (NGUIRichContentLabel.splitSign);
if (splitStr != null && splitStr.Length > 1)
{
this.content = splitStr [0];
init = ParseFontSet (splitStr,instance);
sourceContent = content;
parent = instance;
labels = new List<UILabel> ();
}
if (init)
labels.Add(AddComponent (this.content));
}
UILabel AddComponent(string contentSingle,int width = 0, int height = 0)
{
GameObject o = new GameObject();
o.name = "Lable";
o.layer = parent.gameObject.layer;
o.transform.parent = parent.gameObject.transform;
o.transform.localScale = Vector3.one;
o.transform.localPosition = Vector3.zero;
UILabel label = o.AddComponent<UILabel>() as UILabel;
label.trueTypeFont = parent.currentFont;
label.color = NGUIText.ParseColor(fontColor, 0);
label.fontSize = FontSize;
label.keepCrispWhenShrunk = UILabel.Crispness.Never;
label.useFloatSpacing = true;
label.floatSpacingX = parent.spaceX;
if (!string.IsNullOrEmpty(OutLineColor))
{
label.effectStyle = UILabel.Effect.Outline;
label.effectColor = NGUITools.ParseColor (OutLineColor,0);
label.effectDistance = new Vector2 (0,0);
}
else
label.effectStyle = UILabel.Effect.None;
label.depth = 0;
label.pivot = UIWidget.Pivot.TopLeft;
label.alignment = NGUIText.Alignment.Left;
label.overflowMethod = UILabel.Overflow.ResizeFreely;
label.text = contentSingle;
if (type == ContentType.testCanClick)
{
BoxCollider colider = o.AddComponent<BoxCollider> ();
Vector3 colidersize = new Vector3 (label.width,label.fontSize,0);
colider.size = colidersize;
colider.center = new Vector3 (label.width / 2, -label.fontSize / 2,0);
UIEventListener.Get (label.gameObject).onClick = ClickThisLabel;
}
return label;
}
public void ResetPosition(ref Vector2 pos,ref int maxHeightofthisLine,ref List<UIWidget> currentLine)
{
//超越右邊界
if (pos.x + labels [0].width > parent.Width)
{
string allContent = content;
//需要將當前文本分割成若干段
int widthNeed = labels [0].width - (parent.Width - (int)pos.x);
string cutOut = parent.subStringBylength (labels[0],allContent,parent.Width - pos.x);
//---------------------------------加入殘餘的半行或整行-----------------------------------
if (!string.IsNullOrEmpty(cutOut))
{
labels [0].text = cutOut;
labels [0].transform.localPosition = new Vector3 (pos.x,pos.y,0);
//整行對其
currentLine.Add (labels [0]);
base.AdjustAllLine (currentLine,maxHeightofthisLine,pos.y);
}
else
{
labels [0].transform.localPosition = new Vector3 (pos.x,pos.y,0);
labels [0].text = string.Empty;
}
//--------------------------------------截取整行----------------------------------------
//設置新行起點
pos.x = 0;
pos.y -= Mathf.Max(maxHeightofthisLine, labels [0].fontSize);
pos.y -= parent.spaceY;
maxHeightofthisLine = 0; //新增一行需把最大高度置0
allContent = allContent.Substring (cutOut.Length,allContent.Length - cutOut.Length);
int wholeRaw = widthNeed / parent.Width;
UILabel generate = null;
for (int i = 0; i < wholeRaw; i++)
{
cutOut = parent.subStringBylength (labels[0],allContent,parent.Width);
//加入整行
if (!cutOut.Equals (string.Empty))
{
generate = AddComponent (cutOut,(parent.Width - (int)pos.x),labels [0].height);
labels.Add (generate);
//設置位置
generate.transform.localPosition = new Vector3 (pos.x,pos.y,0f);
pos.x = 0;
pos.y -= Mathf.Max(maxHeightofthisLine, generate.fontSize);
pos.y -= parent.spaceY;
maxHeightofthisLine = 0;//新增一行需把最大高度置0
allContent = allContent.Substring (cutOut.Length,allContent.Length - cutOut.Length);
}
}
// 進入下一行之前,清空緩存
currentLine.Clear ();
//--------------------------------------截取剩餘行----------------------------------------
//裁剪整行後,剩餘半行
if (widthNeed % parent.Width != 0 && !allContent.Equals(string.Empty))
{
generate = AddComponent (allContent,widthNeed % parent.Width,labels [0].height);
labels.Add (generate);
generate.transform.localPosition = new Vector3 (pos.x,pos.y,0f);
pos.x += generate.width;
maxHeightofthisLine = generate.fontSize;
currentLine.Add (generate);
}
}
else
{
labels [0].transform.localPosition = new Vector3 (pos.x,pos.y,0f);
pos.x += labels [0].width;
if (labels [0].height > maxHeightofthisLine)
maxHeightofthisLine = labels [0].height;
currentLine.Add (labels [0]);
}
//根據對其方式,整行對其
base.AdjustAllLine (currentLine, maxHeightofthisLine,pos.y);
}
public void DestorySelf()
{
for (int i = 0; i < labels.Count; i++)
{
GameObject.DestroyImmediate (labels[i].gameObject);
}
labels.Clear ();
}
bool ParseFontSet(string[] splitStr, NGUIRichContentLabel instance)
{
//文本@字號@字體顏色@描邊顏色@message
try
{
if (splitStr.Length >= 2)
FontSize = int.Parse (splitStr [1]);
else
FontSize = instance.DefaultFontSize;
if (splitStr.Length >= 3)
fontColor = splitStr [2];
else
fontColor = instance.sDefaultColor;
if (splitStr.Length >= 4)
OutLineColor = splitStr [3];
else
OutLineColor = string.Empty;
if(splitStr.Length >=5)
messageContent = splitStr [4];
else
messageContent = string.Empty;
return true;
}
catch
{
return false;
}
}
void ClickThisLabel(GameObject obj)
{
if (parent.OnClick != null)
parent.OnClick (messageContent);
}
}
public class RichIcon: RichContentUnit
{
public string IconName;
public string AtlasName;
public int width;
public int height;
public UISprite sprite;
public RichIcon(ContentType unitType, string content, NGUIRichContentLabel instance)
{
type = unitType;
//圖片名字@圖集名字@寬度@高度@message信息(點擊時回傳) ----圖集圖片
string[] splitStr = content.Split (NGUIRichContentLabel.splitSign);
if (splitStr != null && splitStr.Length >= 4)
{
try
{
IconName = splitStr [0];
AtlasName = splitStr [1];
width = int.Parse (splitStr [2]);
height = int.Parse (splitStr [3]);
if (splitStr.Length >= 5)
messageContent = splitStr [4];
else
messageContent = string.Empty;
parent = instance;
init = true;
}
catch
{
init = false;
Logger.ErrorLog (string.Concat( "RichIcon 構造函數出錯 content :",content));
}
}
if (init)
SetComponent ();
}
void SetComponent()
{
GameObject o = new GameObject();
o.name = "icon";
o.layer = parent.gameObject.layer;
o.transform.parent = parent.gameObject.transform;
o.transform.localScale = Vector3.one;
o.transform.localPosition = Vector3.zero;
sprite = o.AddComponent<UISprite> () as UISprite;
sprite.atlas = parent.GetAtlas(AtlasName);
sprite.depth = 0;
sprite.width = this.width;
sprite.height = this.height;
sprite.pivot = UIWidget.Pivot.TopLeft;
if (type == ContentType.iconCanClick)
{
BoxCollider colider = o.AddComponent<BoxCollider> ();
colider.size = new Vector3 (this.width,this.height,0);
colider.center = new Vector3 (this.width / 2, -this.height / 2);
//回調處理
UIEventListener.Get(sprite.gameObject).onClick = ClickThisIcon;
}
if (!string.IsNullOrEmpty (AtlasName) && sprite.atlas != null) //圖集圖片
{
sprite.spriteName = IconName;
}
}
public void ResetPosition(ref Vector2 pos,ref int maxHeightofthisLine,ref List<UIWidget> currentLine)
{
//超越右邊界
if (pos.x + sprite.width > parent.Width)
{
//重置基準點至下一行
pos.x = 0;
pos.y -= maxHeightofthisLine;
pos.y -= parent.spaceY;
maxHeightofthisLine = 0;
currentLine.Clear ();
}
sprite.transform.localPosition = new Vector3 (pos.x,pos.y,0f);
pos.x += sprite.width;
if (sprite.height > maxHeightofthisLine)
maxHeightofthisLine = sprite.height;
currentLine.Add (sprite);
//根據對其方式,整行對其
base.AdjustAllLine (currentLine, maxHeightofthisLine,pos.y);
}
public void DestorySelf()
{
if (sprite != null)
GameObject.DestroyImmediate (sprite.gameObject);
sprite = null;
}
void ClickThisIcon(GameObject obj)
{
if (parent.OnClick != null)
parent.OnClick (messageContent);
}
}
public class RichTexture: RichContentUnit
{
public string IconName;
public int width;
public int height;
public UITexture texture;
public RichTexture(ContentType unitType,string content, NGUIRichContentLabel instance)
{
type = unitType;
//圖片名字@寬度@高度@message(點擊時回傳) ----紋理圖片
string[] splitStr = content.Split (NGUIRichContentLabel.splitSign);
if (splitStr != null && splitStr.Length >= 3)
{
IconName = splitStr [0];
width = int.Parse (splitStr [1]);
height = int.Parse (splitStr [2]);
if (splitStr.Length >= 4)
messageContent = splitStr [3];
else
messageContent = string.Empty;
parent = instance;
init = true;
}
if (init)
SetComponent ();
}
void SetComponent()
{
GameObject o = new GameObject();
o.name = "texture";
o.layer = parent.gameObject.layer;
o.transform.parent = parent.gameObject.transform;
o.transform.localScale = Vector3.one;
o.transform.localPosition = Vector3.zero;
texture = o.AddComponent<UITexture> () as UITexture;
texture.depth = 0;
texture.width = this.width;
texture.height = this.height;
texture.pivot = UIWidget.Pivot.TopLeft;
if (type == ContentType.textureCanClick)
{
BoxCollider colider = o.AddComponent<BoxCollider> ();
colider.size = new Vector3 (this.width,this.height,0);
colider.center = new Vector3 (this.width / 2, -this.height / 2);
//回調處理
UIEventListener.Get(texture.gameObject).onClick = ClickThisTexture;
}
if (!string.IsNullOrEmpty (IconName)) //圖集圖片
{
//CommonUtils.SetTextureAsync (texture,IconName);
}
}
public void ResetPosition(ref Vector2 pos,ref int maxHeightofthisLine,ref List<UIWidget> currentLine)
{
//超越右邊界
if (pos.x + texture.width > parent.Width)
{
//重置基準點至下一行
pos.x = 0;
pos.y -= maxHeightofthisLine;
pos.y -= parent.spaceY;
maxHeightofthisLine = 0;
currentLine.Clear ();
}
texture.transform.localPosition = new Vector3 (pos.x,pos.y,0f);
pos.x += texture.width;
if (texture.height > maxHeightofthisLine)
maxHeightofthisLine = texture.height;
currentLine.Add (texture);
//根據對其方式,整行對其
base.AdjustAllLine (currentLine, maxHeightofthisLine,pos.y);
}
public void DestorySelf()
{
if (texture != null)
GameObject.DestroyImmediate (texture.gameObject);
texture = null;
}
void ClickThisTexture(GameObject obj)
{
if (parent.OnClick != null)
parent.OnClick (messageContent);
}
}
public class RichNewLine : RichContentUnit
{
public RichNewLine (string content, NGUIRichContentLabel instance)
{
this.type = ContentType.newLine;
this.init = true;
this.parent = instance;
}
public void ResetPosition(ref Vector2 pos,ref int maxHeightofthisLine,ref List<UIWidget> currentLine)
{
pos.y -= (maxHeightofthisLine + parent.DefaultFontSize);
pos.y -= parent.spaceY;
pos.x = 0;
maxHeightofthisLine = 0;
currentLine.Clear ();
}
}
組件類:using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
public class NGUIRichContentLabel : MonoBehaviour {
public string Content = string.Empty;
public int Width = 500;
public int Height = 500;
public List<Font> unityFont = null;
public int fontIndex = 0;
public int DefaultFontSize = 20;
public List<UIAtlas> Atlases = null;
public string sDefaultColor = "[ffffffff]";
public Color DefaultColor = Color.white;
public float spaceX = 0;
public float spaceY = 0;
#region 屬性接口
public string SetContent
{
get
{
return Content;
}
set
{
this.Content = value;
FillAll ();
}
}
public int SetWdith
{
get
{
return this.Width;
}
set
{
this.Width = value;
FillAll ();
}
}
public int SetHeight
{
get
{
return this.Height;
}
set
{
this.Height = value;
FillAll ();
}
}
public int SetFontIndex
{
get
{
return fontIndex;
}
set
{
this.fontIndex = value;
FillAll ();
}
}
public int SetDefaultFontSize
{
get
{
return DefaultFontSize;
}
set
{
this.DefaultFontSize = value;
FillAll ();
}
}
public string SetDefaultColor
{
get
{
return sDefaultColor;
}
set
{
this.sDefaultColor = value;
this.DefaultColor = NGUIText.ParseColor(this.sDefaultColor, 0);
FillAll ();
}
}
public Font currentFont
{
get
{
if (unityFont != null && fontIndex < unityFont.Count)
return unityFont [fontIndex];
return null;
}
}
//獲取目標圖集
public UIAtlas GetAtlas(string atlasName)
{
foreach (UIAtlas atlas in Atlases)
{
if (atlas.name.Equals (atlasName))
{
return atlas;
break;
}
}
return null;
}
#endregion
//字符串轉義常量
public static char splitSign= '@'; //數據解析分隔符
public static string fontStart = "<font>"; //文本開始
public static string fontEnd = "</font>"; //文本結束
public static string linkStart = "<link>"; //鏈接開始
public static string linkEnd = "</link>"; //鏈接結束
public static string iconStart = "<icon>"; //圖標開始
public static string iconEnd = "</icon>"; //圖標結束
public static string iconClick = "<iconClick>"; //可點擊圖標開始
public static string iconClickEnd = "</iconClick>"; //可點擊圖標結束
public static string textureStart = "<texture>"; //紋理開始
public static string textureEnd = "</texture>"; //紋理結束
public static string textureClick = "<textureClick>"; //可點擊紋理開始
public static string textureClickEnd = "</textureClick>"; //可點擊紋理結束
public static string newLineStart = "<n>"; //換行轉義字符
//所有的富文本單元
List<RichContentUnit> units = new List<RichContentUnit> ();
//分段解析字符
private string[] splitForStart = new string[] { fontStart,iconStart,textureStart};
//UI根節點
private UIRoot _root;
public delegate void ClickRichUnit(string data);
//點擊行爲的回調
public ClickRichUnit OnClick = null;
void Start()
{
GameObject o = NGUITools.GetRoot(gameObject);
if (o != null)
_root = o.GetComponent<UIRoot>() as UIRoot;
}
void Update () {
if (Input.GetKeyUp (KeyCode.F1))
{
//枚舉類型@文本@字號@字體顏色@描邊顏色
Content = "<font>a11111111111111111111111111今天是個好日子,你們覺得呢/反正我覺得挺好,啦啦啦啦啦啦啦啦啦啦啦,話說回來可以啊,alliswell@20@ffffffff@00ff00ff</font>"
+ "<icon>pic_tongyong_faqiu_zhanshi@CommonAtlas@50@50</icon>"
+ "<font>善惡到頭終有報,人間正道是滄桑!@25@07F4E0FF</font>"
+ "<texture>pic_zhujiemian_xiaoditu_yingdi@100@100</texture>"
//+ newLineStart
+ "<font>奧特曼打\n小怪獸@20@ffffffff@ff0000ff</font>";
FillAll ();
}
if (Input.GetKeyUp (KeyCode.F2))
{
FillAll ();
}
}
/// <summary>
/// 重刷富文本
/// </summary>
void FillAll()
{
ClearOld ();
units = TransformToUnit (Content);
UpdateWidget ();
}
/// <summary>
/// 刷新排布
/// </summary>
void UpdateWidget()
{
//當前可排布位置
Vector2 pos = Vector2.zero;
//當前行最大高度
int maxHeightPerLine = 0;
//當前行組件緩存
List<UIWidget> currentLine = new List<UIWidget> ();
for (int i = 0; i < units.Count; i++)
{
if (units [i].type == ContentType.test || units [i].type == ContentType.testCanClick)
((RichLabel)units [i]).ResetPosition (ref pos,ref maxHeightPerLine,ref currentLine);
else if (units [i].type == ContentType.icon|| units [i].type == ContentType.iconCanClick)
((RichIcon)units [i]).ResetPosition (ref pos,ref maxHeightPerLine,ref currentLine);
else if (units [i].type == ContentType.texture || units [i].type == ContentType.textureCanClick )
((RichTexture)units [i]).ResetPosition (ref pos,ref maxHeightPerLine,ref currentLine);
else if (units [i].type == ContentType.newLine)
((RichNewLine)units [i]).ResetPosition (ref pos,ref maxHeightPerLine,ref currentLine);
}
}
/// <summary>
/// 清除組件
/// </summary>
void ClearOld()
{
for (int i = 0; i < units.Count; i++)
{
if (units [i].type == ContentType.test || units [i].type == ContentType.testCanClick)
((RichLabel)units [i]).DestorySelf ();
else if (units [i].type == ContentType.icon|| units [i].type == ContentType.iconCanClick)
((RichIcon)units [i]).DestorySelf ();
else if (units [i].type == ContentType.texture|| units [i].type == ContentType.textureCanClick)
((RichTexture)units [i]).DestorySelf ();
}
units.Clear ();
}
/// <summary>
/// 源字符串解析
/// </summary>
/// <returns>The to unit.</returns>
/// <param name="content">Content.</param>
List<RichContentUnit> TransformToUnit(string content)
{
List<RichContentUnit> returnValue = new List<RichContentUnit> ();
string[] newLineParse = content.Split (new string[] { newLineStart},System.StringSplitOptions.RemoveEmptyEntries);
for (int index = 0; index < newLineParse.Length; index++)
{
string[] res = newLineParse[index].Split (splitForStart,System.StringSplitOptions.RemoveEmptyEntries);
for(int i = 0; i < res.Length;i++)
{
switch (GenerateType (ref res [i]))
{
case ContentType.icon:
returnValue.Add (new RichIcon(ContentType.icon,res [i],this));
break;
case ContentType.iconCanClick:
returnValue.Add (new RichIcon(ContentType.iconCanClick,res [i],this));
break;
case ContentType.test:
returnValue.Add (new RichLabel(ContentType.test,res [i],this));
break;
case ContentType.testCanClick:
returnValue.Add (new RichLabel(ContentType.testCanClick,res [i],this));
break;
case ContentType.texture:
returnValue.Add (new RichTexture(ContentType.texture,res [i],this));
break;
case ContentType.textureCanClick:
returnValue.Add (new RichTexture(ContentType.textureCanClick,res [i],this));
break;
case ContentType.none:
continue;
}
}
//換行
if(index < newLineParse.Length - 1)
returnValue.Add (new RichNewLine(newLineStart,this));
}
return returnValue;
}
/// <summary>
/// 解析Unit類型
/// </summary>
/// <returns>The type.</returns>
/// <param name="content">Content.</param>
ContentType GenerateType(ref string content)
{
if (content.Contains (fontEnd))
{
content = content.Replace (fontEnd,string.Empty);
return ContentType.test;
}
else if (content.Contains (linkEnd))
{
content = content.Replace (fontEnd,string.Empty);
return ContentType.testCanClick;
}
else if (content.Contains (iconEnd))
{
content = content.Replace (iconEnd,string.Empty);
return ContentType.icon;
}
else if ( content.Contains (iconClickEnd))
{
content = content.Replace (iconEnd,string.Empty);
return ContentType.iconCanClick;
}
else if (content.Contains (textureEnd))
{
content = content.Replace (textureEnd,string.Empty);
return ContentType.texture;
}
else if (content.Contains (textureClickEnd))
{
content = content.Replace (textureEnd,string.Empty);
return ContentType.textureCanClick;
}
return ContentType.none;
}
/// <summary>
/// 字符串按寬度截取
/// </summary>
/// <returns>The string bylength.</returns>
/// <param name="label">Label.</param>
/// <param name="content">Content.</param>
/// <param name="length">Length.</param>
public string subStringBylength(UILabel label, string content, float length)
{
//需取出更準確的字體大小
float realWidth = 0;
for (int i = 0; i < content.Length; i++)
{
realWidth += GetGlyphWidth (label,content[i],0);
if (realWidth > length)
{
return content.Substring (0,i);
}
realWidth += spaceX;
}
return content;
}
//// <summary>
/// 獲得文字的寬
/// 使用字號,快速但不準確
/// </summary>
float GetFontSizeWidth(UILabel label)
{
if (label == null) return 0f;
return label.fontSize;
}
//// <summary>
/// 獲得文字的寬
/// 使用NGUIText函數
/// </summary>
float GetNGUITextGlyphWidth(UILabel label, int ch, int prev)
{
if (label == null) return 0f;
//準備數據
bool keepCrisp;
float pixelDensity;
int finalSize;
float fontScale;
if (label.trueTypeFont != null)
{
NGUIText.dynamicFont = label.trueTypeFont;
NGUIText.bitmapFont = null;
}
else
{
NGUIText.bitmapFont = label.font;
NGUIText.dynamicFont = null;
}
if (label.trueTypeFont != null && label.keepCrispWhenShrunk != UILabel.Crispness.Never)
{
#if UNITY_IPHONE || UNITY_ANDROID || UNITY_WP8 || UNITY_WP_8_1 || UNITY_BLACKBERRY
keepCrisp = (label.keepCrispWhenShrunk == UILabel.Crispness.Always);
#else
keepCrisp = true;
#endif
}
else
keepCrisp = false;
pixelDensity = 1.0f;
if (label.trueTypeFont != null && keepCrisp)
pixelDensity = (_root != null) ? _root.pixelSizeAdjustment : 1f;
else
pixelDensity = 1f;
finalSize = Mathf.RoundToInt(label.fontSize / pixelDensity);
fontScale = 1.0f;
//
NGUIText.fontStyle = label.fontStyle;
NGUIText.finalSize = finalSize;
NGUIText.pixelDensity = pixelDensity;
NGUIText.fontScale = fontScale;
NGUIText.Update(true);
return NGUIText.GetGlyphWidth(ch, prev,fontScale); //2018/1/22
}
//// <summary>
/// 獲得文字的寬
/// 使用unity內部函數
/// </summary>
float GetGlyphWidth(UILabel label,int ch, int prev)
{
if (label == null) return 0f;
//準備數據
bool keepCrisp;
float pixelDensity;
int finalSize;
float fontScale;
if (label.trueTypeFont != null && label.keepCrispWhenShrunk != UILabel.Crispness.Never)
{
#if UNITY_IPHONE || UNITY_ANDROID || UNITY_WP8 || UNITY_WP_8_1 || UNITY_BLACKBERRY
keepCrisp = (label.keepCrispWhenShrunk == UILabel.Crispness.Always);
#else
keepCrisp = true;
#endif
}
else
keepCrisp = false;
pixelDensity = 1.0f;
if (label.trueTypeFont != null && keepCrisp)
pixelDensity = (_root != null) ? _root.pixelSizeAdjustment : 1f;
else
pixelDensity = 1f;
finalSize = Mathf.RoundToInt(label.fontSize / pixelDensity);
fontScale = 1.0f;
//
label.trueTypeFont.RequestCharactersInTexture(label.text, finalSize, label.fontStyle);
if (label.trueTypeFont != null)
{
CharacterInfo mTempChar;
if (label.trueTypeFont.GetCharacterInfo((char)ch, out mTempChar, finalSize, label.fontStyle))
#if UNITY_4_3 || UNITY_4_5 || UNITY_4_6
return mTempChar.width * fontScale * pixelDensity;
#else
return mTempChar.advance * fontScale * pixelDensity;
#endif
}
return 0f;
}
}