/// <summary> /// Different line wrapping functionality -- contributed by MightyM. /// http://www.tasharen.com/forum/index.php?topic=1049.0 /// </summary> public string GetEndOfLineThatFits(string text, float maxWidth, bool encoding, SymbolStyle symbolStyle) { if (mReplacement != null) { return(mReplacement.GetEndOfLineThatFits(text, maxWidth, encoding, symbolStyle)); } int lineWidth = Mathf.RoundToInt(maxWidth * size); if (lineWidth < 1) { return(text); } int textLength = text.Length; int remainingWidth = lineWidth; BMGlyph followingGlyph = null; int currentCharacterIndex = textLength; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols; while (currentCharacterIndex > 0 && remainingWidth > 0) { char currentCharacter = text[--currentCharacterIndex]; // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, currentCharacterIndex, textLength) : null; // Calculate how wide this symbol or character is going to be int glyphWidth = mSpacingX; if (symbol != null && symbol.Validate(atlas)) { glyphWidth += symbol.advance; } else { // Find the glyph for this character BMGlyph glyph = mFont.GetGlyph(currentCharacter); if (glyph != null) { glyphWidth += glyph.advance + ((followingGlyph == null) ? 0 : followingGlyph.GetKerning(currentCharacter)); followingGlyph = glyph; } else { followingGlyph = null; continue; } } // Remaining width after this glyph gets printed remainingWidth -= glyphWidth; } if (remainingWidth < 0) { ++currentCharacterIndex; } return(text.Substring(currentCharacterIndex, textLength - currentCharacterIndex)); }
private BMSymbol MatchSymbol(string text, int offset, int textLength) { int count = this.mSymbols.Count; if (count != 0) { textLength -= offset; for (int i = 0; i < count; i++) { BMSymbol symbol = this.mSymbols[i]; int length = symbol.length; if ((length != 0) && (textLength >= length)) { bool flag = true; for (int j = 0; j < length; j++) { if (text[offset + j] != symbol.sequence[j]) { flag = false; break; } } if (flag && symbol.Validate(this.atlas)) { return(symbol); } } } } return(null); }
public BMSymbol MatchSymbol(string text, int offset, int textLength) { int count = mSymbols.Count; if (count == 0) { return(null); } textLength -= offset; for (int i = 0; i < count; i++) { BMSymbol bMSymbol = mSymbols[i]; int length = bMSymbol.length; if (length != 0 && textLength >= length) { bool flag = true; for (int j = 0; j < length; j++) { if (text[offset + j] != bMSymbol.sequence[j]) { flag = false; break; } } if (flag && bMSymbol.Validate(atlas)) { return(bMSymbol); } } } return(null); }
public BMSymbol MatchSymbol(string text, int offset, int textLength) { int count = this.mSymbols.get_Count(); if (count == 0) { return null; } textLength -= offset; for (int i = 0; i < count; i++) { BMSymbol bMSymbol = this.mSymbols.get_Item(i); int length = bMSymbol.length; if (length != 0 && textLength >= length) { bool flag = true; for (int j = 0; j < length; j++) { if (text.get_Chars(offset + j) != bMSymbol.sequence.get_Chars(j)) { flag = false; break; } } if (flag && bMSymbol.Validate(this.atlas)) { return bMSymbol; } } } return null; }
public BMSymbol MatchSymbol(String text, Int32 offset, Int32 textLength) { Int32 count = this.mSymbols.Count; if (count == 0) { return((BMSymbol)null); } textLength -= offset; for (Int32 i = 0; i < count; i++) { BMSymbol bmsymbol = this.mSymbols[i]; Int32 length = bmsymbol.length; if (length != 0 && textLength >= length) { Boolean flag = true; for (Int32 j = 0; j < length; j++) { if (text[offset + j] != bmsymbol.sequence[j]) { flag = false; break; } } if (flag && bmsymbol.Validate(this.atlas)) { return(bmsymbol); } } } return((BMSymbol)null); }
static public int Validate(IntPtr l) { try { BMSymbol self = (BMSymbol)checkSelf(l); UIAtlas a1; checkType(l, 2, out a1); var ret = self.Validate(a1); pushValue(l, true); pushValue(l, ret); return(2); } catch (Exception e) { return(error(l, e)); } }
/// <summary> /// Retrieve the symbol at the beginning of the specified sequence, if a match is found. /// </summary> public BMSymbol MatchSymbol(string text, int offset, int textLength) { // No symbols present int count = mSymbols.Count; if (count == 0) { return(null); } textLength -= offset; // Run through all symbols for (int i = 0; i < count; ++i) { BMSymbol sym = mSymbols[i]; // If the symbol's length is longer, move on int symbolLength = sym.length; if (symbolLength == 0 || textLength < symbolLength) { continue; } bool match = true; // Match the characters for (int c = 0; c < symbolLength; ++c) { if (text[offset + c] != sym.sequence[c]) { match = false; break; } } // Match found if (match && sym.Validate(atlas)) { return(sym); } } return(null); }
// Token: 0x060006C5 RID: 1733 RVA: 0x00037A38 File Offset: 0x00035C38 public BMSymbol MatchSymbol(string text, int offset, int textLength) { INGUIFont replacement = this.replacement; if (replacement != null) { return(replacement.MatchSymbol(text, offset, textLength)); } int count = this.mSymbols.Count; if (count == 0) { return(null); } textLength -= offset; for (int i = 0; i < count; i++) { BMSymbol bmsymbol = this.mSymbols[i]; int length = bmsymbol.length; if (length != 0 && textLength >= length) { bool flag = true; for (int j = 0; j < length; j++) { if (text[offset + j] != bmsymbol.sequence[j]) { flag = false; break; } } if (flag && bmsymbol.Validate(this.atlas)) { return(bmsymbol); } } } return(null); }
public void Print(string text, Color32 color, BetterList <Vector3> verts, BetterList <Vector2> uvs, BetterList <Color32> cols, bool encoding, SymbolStyle symbolStyle, Alignment alignment, int lineWidth, bool premultiply) #endif { if (mReplacement != null) { mReplacement.Print(text, color, verts, uvs, cols, encoding, symbolStyle, alignment, lineWidth, premultiply); } else if (mFont != null && text != null) { if (!mFont.isValid) { Debug.LogError("Attempting to print using an invalid font!"); return; } mColors.Clear(); mColors.Add(color); Vector2 scale = mFont.charSize > 0 ? new Vector2(1f / mFont.charSize, 1f / mFont.charSize) : Vector2.one; int indexOffset = verts.size; int maxX = 0; int x = 0; int y = 0; int prev = 0; int lineHeight = (mFont.charSize + mSpacingY); Vector3 v0 = Vector3.zero, v1 = Vector3.zero; Vector2 u0 = Vector2.zero, u1 = Vector2.zero; float invX = uvRect.width / mFont.texWidth; float invY = mUVRect.height / mFont.texHeight; int textLength = text.Length; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols && sprite != null; for (int i = 0; i < textLength; ++i) { char c = text[i]; if (c == '\n') { if (x > maxX) { maxX = x; } if (alignment != Alignment.Left) { Align(verts, indexOffset, alignment, x, lineWidth); indexOffset = verts.size; } x = 0; y += lineHeight; prev = 0; continue; } if (c < ' ') { prev = 0; continue; } if (encoding && c == '[') { int retVal = NGUITools.ParseSymbol(text, i, mColors, premultiply); if (retVal > 0) { color = mColors[mColors.Count - 1]; i += retVal - 1; continue; } } // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, i, textLength) : null; if (symbol == null || !symbol.Validate(atlas)) { BMGlyph glyph = mFont.GetGlyph(c); if (glyph == null) { continue; } if (prev != 0) { x += glyph.GetKerning(prev); } if (c == ' ') { x += mSpacingX + glyph.advance; prev = c; continue; } v0.x = scale.x * (x + glyph.offsetX); v0.y = -scale.y * (y + glyph.offsetY); v1.x = v0.x + scale.x * glyph.width; v1.y = v0.y - scale.y * glyph.height; u0.x = mUVRect.xMin + invX * glyph.x; u0.y = mUVRect.yMax - invY * glyph.y; u1.x = u0.x + invX * glyph.width; u1.y = u0.y - invY * glyph.height; x += mSpacingX + glyph.advance; prev = c; if (glyph.channel == 0 || glyph.channel == 15) { for (int b = 0; b < 4; ++b) { cols.Add(color); } } else { // Packed fonts come as alpha masks in each of the RGBA channels. // In order to use it we need to use a special shader. // // Limitations: // - Effects (drop shadow, outline) will not work. // - Should not be a part of the atlas (eastern fonts rarely are anyway). // - Lower color precision Color col = color; col *= 0.49f; switch (glyph.channel) { case 1: col.b += 0.51f; break; case 2: col.g += 0.51f; break; case 4: col.r += 0.51f; break; case 8: col.a += 0.51f; break; } for (int b = 0; b < 4; ++b) { cols.Add(col); } } } else { v0.x = scale.x * (x + symbol.offsetX); v0.y = -scale.y * (y + symbol.offsetY); v1.x = v0.x + scale.x * symbol.width; v1.y = v0.y - scale.y * symbol.height; Rect uv = symbol.uvRect; u0.x = uv.xMin; u0.y = uv.yMax; u1.x = uv.xMax; u1.y = uv.yMin; x += mSpacingX + symbol.advance; i += symbol.length - 1; prev = 0; if (symbolStyle == SymbolStyle.Colored) { for (int b = 0; b < 4; ++b) { cols.Add(color); } } else { Color32 col = Color.white; col.a = color.a; for (int b = 0; b < 4; ++b) { cols.Add(col); } } } verts.Add(new Vector3(v1.x, v0.y)); verts.Add(new Vector3(v1.x, v1.y)); verts.Add(new Vector3(v0.x, v1.y)); verts.Add(new Vector3(v0.x, v0.y)); uvs.Add(new Vector2(u1.x, u0.y)); uvs.Add(new Vector2(u1.x, u1.y)); uvs.Add(new Vector2(u0.x, u1.y)); uvs.Add(new Vector2(u0.x, u0.y)); } if (alignment != Alignment.Left && indexOffset < verts.size) { Align(verts, indexOffset, alignment, x, lineWidth); indexOffset = verts.size; } } }
/// <summary> /// Text wrapping functionality. The 'maxWidth' should be in local coordinates (take pixels and divide them by transform's scale). /// </summary> public string WrapText(string text, float maxWidth, int maxLineCount, bool encoding, SymbolStyle symbolStyle) { if (mReplacement != null) { return(mReplacement.WrapText(text, maxWidth, maxLineCount, encoding, symbolStyle)); } // Width of the line in pixels int lineWidth = Mathf.RoundToInt(maxWidth * size); if (lineWidth < 1) { return(text); } StringBuilder sb = new StringBuilder(); int textLength = text.Length; int remainingWidth = lineWidth; int previousChar = 0; int start = 0; int offset = 0; bool lineIsEmpty = true; bool multiline = (maxLineCount != 1); int lineCount = 1; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols; // Run through all characters for (; offset < textLength; ++offset) { char ch = text[offset]; // New line character -- start a new line if (ch == '\n') { if (!multiline || lineCount == maxLineCount) { break; } remainingWidth = lineWidth; // Add the previous word to the final string if (start < offset) { sb.Append(text.Substring(start, offset - start + 1)); } else { sb.Append(ch); } lineIsEmpty = true; ++lineCount; start = offset + 1; previousChar = 0; continue; } // If this marks the end of a word, add it to the final string. if (ch == ' ' && previousChar != ' ' && start < offset) { sb.Append(text.Substring(start, offset - start + 1)); lineIsEmpty = false; start = offset + 1; previousChar = ch; } // When encoded symbols such as [RrGgBb] or [-] are encountered, skip past them if (encoding && ch == '[') { if (offset + 2 < textLength) { if (text[offset + 1] == '-' && text[offset + 2] == ']') { offset += 2; continue; } else if (offset + 7 < textLength && text[offset + 7] == ']') { if (NGUITools.EncodeColor(NGUITools.ParseColor(text, offset + 1)) == text.Substring(offset + 1, 6).ToUpper()) { offset += 7; continue; } } } } // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, offset, textLength) : null; // Calculate how wide this symbol or character is going to be int glyphWidth = mSpacingX; if (symbol != null && symbol.Validate(atlas)) { glyphWidth += symbol.advance; } else { // Find the glyph for this character BMGlyph glyph = (symbol == null) ? mFont.GetGlyph(ch) : null; if (glyph != null) { glyphWidth += (previousChar != 0) ? glyph.advance + glyph.GetKerning(previousChar) : glyph.advance; } else { continue; } } // Remaining width after this glyph gets printed remainingWidth -= glyphWidth; // Doesn't fit? if (remainingWidth < 0) { // Can't start a new line if (lineIsEmpty || !multiline || lineCount == maxLineCount) { // This is the first word on the line -- add it up to the character that fits sb.Append(text.Substring(start, Mathf.Max(0, offset - start))); if (!multiline || lineCount == maxLineCount) { start = offset; break; } EndLine(ref sb); // Start a brand-new line lineIsEmpty = true; ++lineCount; if (ch == ' ') { start = offset + 1; remainingWidth = lineWidth; } else { start = offset; remainingWidth = lineWidth - glyphWidth; } previousChar = 0; } else { // Skip all spaces before the word while (start < textLength && text[start] == ' ') { ++start; } // Revert the position to the beginning of the word and reset the line lineIsEmpty = true; remainingWidth = lineWidth; offset = start - 1; previousChar = 0; if (!multiline || lineCount == maxLineCount) { break; } ++lineCount; EndLine(ref sb); continue; } } else { previousChar = ch; } // Advance the offset past the symbol if (symbol != null) { offset += symbol.length - 1; previousChar = 0; } } if (start < offset) { sb.Append(text.Substring(start, offset - start)); } return(sb.ToString()); }
/// <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; if (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text)) { if (encoding) { text = NGUITools.StripSymbols(text); } int length = text.Length; int maxX = 0; int x = 0; int y = 0; int prev = 0; int lineHeight = (mFont.charSize + 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; } // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, i, length) : null; if (symbol == null || !symbol.Validate(atlas)) { // 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.advance; i += symbol.length - 1; prev = 0; } } // Convert from pixel coordinates to local coordinates float scale = (mFont.charSize > 0) ? 1f / mFont.charSize : 1f; v.x = scale * ((x > maxX) ? x : maxX); v.y = scale * (y + lineHeight); } return(v); }