/////////////////////////////////////////////////////////////////////////////// // Functions /////////////////////////////////////////////////////////////////////////////// /*public CharInfo GetCharInfo ( char _symbol ) { * if (bitmapFont_ != null) { * return bitmapFont_.GetCharInfo(_symbol); * } * if (dynamicFont_ != null) { * //// yes, Unity's GetCharacterInfo have y problem, you should get lowest character j's y-offset adjust it. * CharacterInfo jCharInfo; * dynamicFont_.RequestCharactersInTexture("j", dynamicFontSize_, dynamicFontStyle_); * dynamicFont_.GetCharacterInfo('j', out jCharInfo, dynamicFontSize_, dynamicFontStyle_); * int ttf_offset = (int)(dynamicFontSize_ + jCharInfo.vert.yMax); * * CharacterInfo dynamicCharInfo; * dynamicFont_.GetCharacterInfo(_symbol, out dynamicCharInfo, dynamicFontSize_, dynamicFontStyle_); * * Texture texture = dynamicFont_.material.mainTexture; * CharInfo charInfo = new CharInfo(); // TODO: use static char info * charInfo.id = _symbol; * charInfo.trim_x = 0; * charInfo.trim_y = 0; * charInfo.x = (int)(dynamicCharInfo.uv.x * texture.width); * charInfo.y = (int)(dynamicCharInfo.uv.yMax * texture.height); * charInfo.width = (int)dynamicCharInfo.vert.width; * charInfo.height = - (int)dynamicCharInfo.vert.height; * charInfo.xoffset = (int)dynamicCharInfo.vert.x; * charInfo.yoffset = - (int)dynamicCharInfo.vert.y; * charInfo.xadvance = (int)dynamicCharInfo.width; * charInfo.rotated = dynamicCharInfo.flipped; * return charInfo; * } * return null; * }*/ public bool GetCharInfo(char _symbol, out CharacterInfo _charInfo) { if (bitmapFont_ != null) { exBitmapFont.CharInfo bitmapCharInfo = bitmapFont_.GetCharInfo(_symbol); if (bitmapCharInfo != null) { _charInfo.flipped = bitmapCharInfo.rotated; _charInfo.index = bitmapCharInfo.id; _charInfo.size = 0; _charInfo.style = FontStyle.Normal; if (bitmapFont_.texture != null) { Vector2 texelSize = bitmapFont_.texture.texelSize; if (bitmapCharInfo.rotated) { _charInfo.uv = new Rect((bitmapCharInfo.x + bitmapCharInfo.rotatedWidth) * texelSize.x, bitmapCharInfo.y * texelSize.y, -bitmapCharInfo.rotatedWidth * texelSize.x, bitmapCharInfo.rotatedHeight * texelSize.y); } else { _charInfo.uv = new Rect(bitmapCharInfo.x * texelSize.x, bitmapCharInfo.y * texelSize.y, bitmapCharInfo.rotatedWidth * texelSize.x, bitmapCharInfo.rotatedHeight * texelSize.y); } } else { _charInfo.uv = new Rect(); } _charInfo.vert = new Rect(bitmapCharInfo.xoffset, -bitmapCharInfo.yoffset, bitmapCharInfo.width, -bitmapCharInfo.height); float baselineOffset = bitmapFont_.size - bitmapFont_.baseLine; _charInfo.vert.y += baselineOffset; _charInfo.width = bitmapCharInfo.xadvance; return(true); } } else if (dynamicFont_ != null) { if (dynamicFont_.GetCharacterInfo(_symbol, out _charInfo, dynamicFontSize_, dynamicFontStyle_)) { _charInfo.vert.y -= baseline; return(true); } } _charInfo = new CharacterInfo(); return(false); }
// ------------------------------------------------------------------ // Desc: This only calculate result in one line // ------------------------------------------------------------------ public static void BuildTextLine( Vector3[] _vertices, Vector2[] _uvs, string _text, exBitmapFont _font, int _lineHeight, int _fontSize, int _wordSpacing, int _letterSpacing ) { int cur_x = 0; int cur_y = 0; // for ( int i = 0; i < _text.Length; ++i ) { char cur_char = _text[i]; // NOTE: we skip new-line operation, since we believe this function only have one-line text if ( cur_char == '\n' ) { continue; } // generate mesh exBitmapFont.CharInfo charInfo = _font.GetCharInfo(cur_char); if ( charInfo != null ) { int idx = 4*i; float x = cur_x + charInfo.xoffset; float y = cur_y + charInfo.yoffset; Vector2 texelSize = _font.texture.texelSize; Vector2 start = new Vector2( charInfo.x * texelSize.x, charInfo.y * texelSize.y ); Vector2 end = new Vector2( (charInfo.x + charInfo.rotatedWidth) * texelSize.x, (charInfo.y + charInfo.rotatedHeight) * texelSize.y ); // build vertices _vertices[idx + 0] = new Vector3(x, y, 0.0f); _vertices[idx + 1] = new Vector3(x + charInfo.width, y, 0.0f); _vertices[idx + 2] = new Vector3(x + charInfo.width, y + charInfo.height, 0.0f); _vertices[idx + 3] = new Vector3(x, y + charInfo.height, 0.0f); // build uv if ( charInfo.rotated ) { _uvs[idx + 0] = new Vector2(end.x, start.y); _uvs[idx + 1] = new Vector2(end.x, end.y); _uvs[idx + 2] = new Vector2(start.x, end.y); _uvs[idx + 3] = new Vector2(start.x, start.y); } else { _uvs[idx + 0] = new Vector2(start.x, end.y); _uvs[idx + 1] = new Vector2(end.x, end.y); _uvs[idx + 2] = new Vector2(end.x, start.y); _uvs[idx + 3] = new Vector2(start.x, start.y); } // advance x cur_x += (int)charInfo.xadvance + _letterSpacing; if ( cur_char == ' ' ) cur_x += _wordSpacing; } } }
// ------------------------------------------------------------------ // Desc: This only calculate result in one line // ------------------------------------------------------------------ public static void BuildTextLine(Vector3[] _vertices, Vector2[] _uvs, string _text, exBitmapFont _font, int _lineHeight, int _fontSize, int _wordSpacing, int _letterSpacing) { int cur_x = 0; int cur_y = 0; // for (int i = 0; i < _text.Length; ++i) { char cur_char = _text[i]; // NOTE: we skip new-line operation, since we believe this function only have one-line text if (cur_char == '\n') { continue; } // generate mesh exBitmapFont.CharInfo charInfo = _font.GetCharInfo(cur_char); if (charInfo != null) { int idx = 4 * i; float x = cur_x + charInfo.xoffset; float y = cur_y + charInfo.yoffset; Vector2 texelSize = _font.texture.texelSize; Vector2 start = new Vector2(charInfo.x * texelSize.x, charInfo.y * texelSize.y); Vector2 end = new Vector2((charInfo.x + charInfo.rotatedWidth) * texelSize.x, (charInfo.y + charInfo.rotatedHeight) * texelSize.y); // build vertices _vertices[idx + 0] = new Vector3(x, y, 0.0f); _vertices[idx + 1] = new Vector3(x + charInfo.width, y, 0.0f); _vertices[idx + 2] = new Vector3(x + charInfo.width, y + charInfo.height, 0.0f); _vertices[idx + 3] = new Vector3(x, y + charInfo.height, 0.0f); // build uv if (charInfo.rotated) { _uvs[idx + 0] = new Vector2(end.x, start.y); _uvs[idx + 1] = new Vector2(end.x, end.y); _uvs[idx + 2] = new Vector2(start.x, end.y); _uvs[idx + 3] = new Vector2(start.x, start.y); } else { _uvs[idx + 0] = new Vector2(start.x, end.y); _uvs[idx + 1] = new Vector2(end.x, end.y); _uvs[idx + 2] = new Vector2(end.x, start.y); _uvs[idx + 3] = new Vector2(start.x, start.y); } // advance x cur_x += (int)charInfo.xadvance + _letterSpacing; if (cur_char == ' ') { cur_x += _wordSpacing; } } } }
/////////////////////////////////////////////////////////////////////////////// // mesh building functions /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public void CalculateSize(out float[] _lineWidths, out float[] _kernings, out float _halfWidthScaled, out float _halfHeightScaled, out float _offsetX, out float _offsetY) { if (useMultiline_) { long lines = exStringHelper.CountLinesInString(text_); _lineWidths = new float[lines]; } else { _lineWidths = new float[0]; } _kernings = new float[Mathf.Max(text_.Length - 1, 0)]; float maxWidth = 0.0f; float curWidth = 0.0f; float height = fontInfo_.lineHeight; int curLine = 0; for (int i = 0; i < text_.Length; ++i) { char c = text_[i]; if (c == '\n') { if (useMultiline_) { if (curWidth > maxWidth) { maxWidth = curWidth; } _lineWidths[curLine] = curWidth; curWidth = 0.0f; height = height + fontInfo_.lineHeight + lineSpacing_; ++curLine; } continue; } // if we don't have the character, it will become space. exBitmapFont.CharInfo charInfo = fontInfo_.GetCharInfo(c); if (charInfo != null) { curWidth = curWidth + charInfo.xadvance + tracking_; if (useKerning_) { if (i < text_.Length - 1) { for (int idx = 0; idx < fontInfo_.kernings.Count; ++idx) { exBitmapFont.KerningInfo k = fontInfo_.kernings[idx]; if (k.first == c && k.second == text_[i + 1]) { curWidth += k.amount; _kernings[i] = k.amount; break; } } } } } } if (curWidth > maxWidth) { maxWidth = curWidth; } if (useMultiline_) { _lineWidths[curLine] = curWidth; } Vector2 finalScale = new Vector2(scale_.x * ppfScale_.x, scale_.y * ppfScale_.y); _halfWidthScaled = maxWidth * finalScale.x * 0.5f; _halfHeightScaled = height * finalScale.y * 0.5f; _offsetX = 0.0f; _offsetY = 0.0f; // calculate anchor offset switch (anchor_) { case Anchor.TopLeft: _offsetX = -_halfWidthScaled; _offsetY = -_halfHeightScaled; break; case Anchor.TopCenter: _offsetX = 0.0f; _offsetY = -_halfHeightScaled; break; case Anchor.TopRight: _offsetX = _halfWidthScaled; _offsetY = -_halfHeightScaled; break; case Anchor.MidLeft: _offsetX = -_halfWidthScaled; _offsetY = 0.0f; break; case Anchor.MidCenter: _offsetX = 0.0f; _offsetY = 0.0f; break; case Anchor.MidRight: _offsetX = _halfWidthScaled; _offsetY = 0.0f; break; case Anchor.BotLeft: _offsetX = -_halfWidthScaled; _offsetY = _halfHeightScaled; break; case Anchor.BotCenter: _offsetX = 0.0f; _offsetY = _halfHeightScaled; break; case Anchor.BotRight: _offsetX = _halfWidthScaled; _offsetY = _halfHeightScaled; break; default: _offsetX = 0.0f; _offsetY = 0.0f; break; } _offsetX -= offset_.x; _offsetY += offset_.y; }