项目中需要文字的背景框自适应文字内容的宽和高,宽很方便确定,在UILabel面板里有这个属性值:
这里的Max Width就是每一行的最大像素个数,Max Lines设置0的意思是没有最大行数限制。
但是行数怎么获取呢,UILabel里并没有这个接口,但是我们知道NGUI要把文字渲染出来,肯定是需要知道渲染范围也就是渲染大小的。
我们先到UILabel类里寻找有没有这样一个方法,然后不小心翻到这个属性:
/// <summary>
/// Visible size of the widget in local coordinates.
/// </summary>
public override Vector2 relativeSize
{
get
{
if (mFont == null) return Vector3.one;
if (hasChanged) ProcessText();
return mSize;
}
}
找到ProcessText()函数,里面有一个调用:
mSize = !string.IsNullOrEmpty(mProcessedText) ? mFont.CalculatePrintedSize(mProcessedText, mEncoding, mSymbols) : Vector2.one;
看这个mSize,没准就是我们要找的变量,然后跟到CalculatePrintedSize函数,看这个是干什么的:
/// <summary>
/// Get the printed size of the specified string. The returned value is in local coordinates. Multiply by transform's scale to get pixels.
/// </summary>
public Vector2 CalculatePrintedSize (string text, bool encoding, SymbolStyle symbolStyle)
{
if (mReplacement != null) return mReplacement.CalculatePrintedSize(text, encoding, symbolStyle);
Vector2 v = Vector2.zero;
bool dynamic = isDynamic;
#if UNITY_3_5
if (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text))
#else
if (dynamic || (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text)))
#endif
{
if (encoding) text = NGUITools.StripSymbols(text);
#if !UNITY_3_5
if (dynamic)
{
mDynamicFont.textureRebuildCallback = OnFontChanged;
mDynamicFont.RequestCharactersInTexture(text, mDynamicFontSize, mDynamicFontStyle);
mDynamicFont.textureRebuildCallback = null;
}
#endif
int length = text.Length;
int maxX = 0;
int x = 0;
int y = 0;
int prev = 0;
int fs = size;
int lineHeight = (fs + mSpacingY);
bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols;
for (int i = 0; i < length; ++i)
{
char c = text[i];
// Start a new line
if (c == '\n')
{
if (x > maxX) maxX = x;
x = 0;
y += lineHeight;
prev = 0;
continue;
}
// Skip invalid characters
if (c < ' ') { prev = 0; continue; }
if (!dynamic)
{
// See if there is a symbol matching this text
BMSymbol symbol = useSymbols ? MatchSymbol(text, i, length) : null;
if (symbol == null)
{
// Get the glyph for this character
BMGlyph glyph = mFont.GetGlyph(c);
if (glyph != null)
{
x += mSpacingX + ((prev != 0) ? glyph.advance + glyph.GetKerning(prev) : glyph.advance);
prev = c;
}
}
else
{
// Symbol found -- use it
x += mSpacingX + symbol.width;
i += symbol.length - 1;
prev = 0;
}
}
#if !UNITY_3_5
else
{
if (mDynamicFont.GetCharacterInfo(c, out mChar, mDynamicFontSize, mDynamicFontStyle))
x += (int)(mSpacingX + mChar.width);
}
#endif
}
// Convert from pixel coordinates to local coordinates
float scale = (fs > 0) ? 1f / fs : 1f;
v.x = scale * ((x > maxX) ? x : maxX);
v.y = scale * (y + lineHeight);
}
return v;
}
函数里面的具体实现先不解释,看这个函数的说明:
Multiply by transform's scale to get pixels.
什么意思呢,意思就是 拿这个函数的返回值,乘以transform的scale值就得到了实际像素大小,所以这个返回值是字体内容的实际渲染大小与transform.localscale的乘数因子,也就是说要获取一个Label的实际像素大小,只要拿这个值也Label.transform.localscale相乘就可以了。