private void DrawCharGlyph(ref Vector2 vAtOriginal, float scale, ref Color currentColor, ref Vector2 vOrigin, ref float pxWidth, ref char cLast, ref Vector2 vAt, int line, char c) { MyGlyphInfo ginfo = m_glyphInfoByChar[c]; // If kerning is enabled, get the kern adjustment for this char pair if (KernEnabled) { int pxKern = CalcKern(cLast, c); vAt.X += pxKern * scale; pxWidth += pxKern * scale; cLast = c; } // This will fix vertical coordinate in case we use "gpad" - left/top blank space in every character vAt.Y = vAtOriginal.Y + (ginfo.pxLeftSideBearing + MyRenderGuiConstants.FONT_TOP_SIDE_BEARING + line * LineHeight) * scale; // Draw the glyph vAt.X += ginfo.pxLeftSideBearing * scale; if (ginfo.pxWidth != 0 && ginfo.pxHeight != 0) { Rectangle rSource = new Rectangle(ginfo.pxLocX, ginfo.pxLocY, ginfo.pxWidth, ginfo.pxHeight); Color color = currentColor; MySpritesRenderer.AddSingleSprite(m_bitmapTextureById[ginfo.nBitmapID], color, Vector2.Zero, Vector2.UnitX, rSource, new RectangleF(vAt.X, vAt.Y, scale * rSource.Width, scale * rSource.Height)); } // update the string width and advance the pen to the next drawing position pxWidth += ginfo.pxAdvanceWidth * scale; vAt.X += (ginfo.pxAdvanceWidth - ginfo.pxLeftSideBearing) * scale; }
/// <summary> /// Load the data from the "glyphs" node /// </summary> /// <param name="xnl">XML node list containing the "glyphs" node's children</param> private void LoadFontXML_glyphs(XmlNodeList xnl) { foreach (XmlNode xn in xnl) { if (xn.Name == "glyph") { string strChar = GetXMLAttribute(xn, "ch"); string strBitmapID = GetXMLAttribute(xn, "bm"); string strLoc = GetXMLAttribute(xn, "loc"); string strSize = GetXMLAttribute(xn, "size"); string strAW = GetXMLAttribute(xn, "aw"); string strLSB = GetXMLAttribute(xn, "lsb"); if (strLoc == "") { strLoc = GetXMLAttribute(xn, "origin"); // obsolete - use loc instead } string[] aLoc = strLoc.Split(','); string[] aSize = strSize.Split('x'); MyGlyphInfo ginfo = new MyGlyphInfo(); ginfo.nBitmapID = UInt16.Parse(strBitmapID); ginfo.pxLocX = ushort.Parse(aLoc[0]); ginfo.pxLocY = ushort.Parse(aLoc[1]); ginfo.pxWidth = Byte.Parse(aSize[0]); ginfo.pxHeight = Byte.Parse(aSize[1]); ginfo.pxAdvanceWidth = Byte.Parse(strAW); ginfo.pxLeftSideBearing = SByte.Parse(strLSB); m_glyphInfoByChar[strChar[0]] = ginfo; } } }
// Calculate the width of the given string. // Returns: Width and height (in pixels) of the string public Vector2 MeasureString(StringBuilder text, float scale) { try { scale *= MyRenderGuiConstants.FONT_SCALE; float pxWidth = 0; char cLast = '\0'; float maxPxWidth = 0; int lines = 1; for (int i = 0; i < text.Length; i++) { char c = text[i]; // New line if (c == NEW_LINE) { lines++; pxWidth = 0; cLast = '\0'; continue; } if (!CanWriteOrReplace(ref c)) { continue; } MyGlyphInfo ginfo = m_glyphInfoByChar[c]; // if kerning is enabled, get the kern adjustment for this char pair if (KernEnabled) { pxWidth += CalcKern(cLast, c); cLast = c; } // update the string width pxWidth += ginfo.pxAdvanceWidth; // Spacing if (i < (text.Length - 1)) { pxWidth += Spacing; } // Because new line if (pxWidth > maxPxWidth) { maxPxWidth = pxWidth; } } return(new Vector2(maxPxWidth * scale, lines * LineHeight * scale)); } catch (System.IndexOutOfRangeException) { return(Vector2.Zero); } }
// Calculate the width of the given string. // Returns: Width and height (in pixels) of the string public Vector2 MeasureString(StringBuilder text, float scale) { scale *= MyGuiConstants.FONT_SCALE; float pxWidth = 0; char cLast = '\0'; float maxPxWidth = 0; int lines = 1; for (int i = 0; i < text.Length; i++) { char c = text[i]; // New line if (c == NEW_LINE) { lines++; pxWidth = 0; cLast = '\0'; continue; } if (!m_dictUnicode2GlyphInfo.ContainsKey(c)) { continue; } MyGlyphInfo ginfo = m_dictUnicode2GlyphInfo[c]; // if kerning is enabled, get the kern adjustment for this char pair if (m_fKern) { pxWidth += CalcKern(cLast, c); cLast = c; } // update the string width pxWidth += ginfo.pxAdvanceWidth; // Spacing if (i < (text.Length - 1)) { pxWidth += Spacing; } // Because new line if (pxWidth > maxPxWidth) { maxPxWidth = pxWidth; } } return(new Vector2(maxPxWidth * scale, lines * LineHeight * scale)); }
protected float ComputeScaledAdvanceWithKern(char c, char cLast, float scale) { MyGlyphInfo ginfo = m_glyphInfoByChar[c]; float advance = 0f; if (KernEnabled) { int pxKern = CalcKern(cLast, c); advance += pxKern * scale; } advance += ginfo.pxAdvanceWidth * scale; return(advance); }
public int ComputeCharsThatFit(StringBuilder text, float scale, float maxTextWidth) { scale *= MyRenderGuiConstants.FONT_SCALE; maxTextWidth /= scale; float pxWidth = 0; char cLast = '\0'; for (int i = 0; i < text.Length; i++) { char c = text[i]; Debug.Assert(c != NEW_LINE); if (!CanWriteOrReplace(ref c)) { continue; } MyGlyphInfo ginfo = m_glyphInfoByChar[c]; // if kerning is enabled, get the kern adjustment for this char pair if (KernEnabled) { pxWidth += CalcKern(cLast, c); cLast = c; } // update the string width pxWidth += ginfo.pxAdvanceWidth; // Spacing if (i < (text.Length - 1)) { pxWidth += Spacing; } // Because new line if (pxWidth > maxTextWidth) { return(i); } } return(text.Length); }
// Private version of DrawString that expects the string to be formatted already // Returns: Width of string (in pixels) float DrawString_internal(Vector2 vAtOriginal, Color cText, StringBuilder text, float scale) { scale *= MyGuiConstants.FONT_SCALE; Color currentColor = cText; Vector2 vOrigin = new Vector2(0, 0); float pxWidth = 0; char cLast = '\0'; Vector2 vAt = vAtOriginal; float spacingScaled = Spacing * scale; int line = 0; // Draw each character in the string for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c == NEW_LINE) { vAt.X = vAtOriginal.X; line++; continue; } if (!m_dictUnicode2GlyphInfo.ContainsKey(c)) { continue; } MyGlyphInfo ginfo = m_dictUnicode2GlyphInfo[c]; // If kerning is enabled, get the kern adjustment for this char pair if (m_fKern) { int pxKern = CalcKern(cLast, c); vAt.X += pxKern * scale; pxWidth += pxKern * scale; cLast = c; } // This will fix vertical coordinate in case we use "gpad" - left/top blank space in every character vAt.Y = vAtOriginal.Y + (ginfo.pxLeftSideBearing + MyGuiConstants.FONT_TOP_SIDE_BEARING + line * LineHeight) * scale; // Draw the glyph vAt.X += ginfo.pxLeftSideBearing * scale; if (ginfo.pxWidth != 0 && ginfo.pxHeight != 0) { Rectangle rSource = new Rectangle(ginfo.pxLocX, ginfo.pxLocY, ginfo.pxWidth, ginfo.pxHeight); Color color = (((ginfo.nFlags & MyGlyphFlags.ForceWhite) != 0) ? Color.White : currentColor); MyGuiManager.DrawSpriteBatch(m_dictBitmapID2Texture[ginfo.nBitmapID], vAt, rSource, color, 0.0f, vOrigin, scale, SpriteEffects.None, m_fpDepth); } // update the string width and advance the pen to the next drawing position pxWidth += ginfo.pxAdvanceWidth * scale; vAt.X += (ginfo.pxAdvanceWidth - ginfo.pxLeftSideBearing) * scale; // Spacing if (i < (text.Length - 1)) { pxWidth += spacingScaled; vAt.X += spacingScaled; } } // Record final pen position and color m_vPen = vAt; m_color = cText; return(pxWidth); }
/// <summary> /// Load the data from the "glyphs" node /// </summary> /// <param name="xnl">XML node list containing the "glyphs" node's children</param> void LoadFontXML_glyphs(XmlNodeList xnl) { foreach (XmlNode xn in xnl) { if (xn.Name == "glyph") { string strChar = GetXMLAttribute(xn, "ch"); string strBitmapID = GetXMLAttribute(xn, "bm"); string strLoc = GetXMLAttribute(xn, "loc"); string strSize = GetXMLAttribute(xn, "size"); string strAW = GetXMLAttribute(xn, "aw"); string strLSB = GetXMLAttribute(xn, "lsb"); string strForceWhite = GetXMLAttribute(xn, "forcewhite"); if (strLoc == "") strLoc = GetXMLAttribute(xn, "origin"); // obsolete - use loc instead string[] aLoc = strLoc.Split(','); string[] aSize = strSize.Split('x'); MyGlyphInfo ginfo = new MyGlyphInfo(); ginfo.nBitmapID = UInt16.Parse(strBitmapID); ginfo.pxLocX = ushort.Parse(aLoc[0]); ginfo.pxLocY = ushort.Parse(aLoc[1]); ginfo.pxWidth = Byte.Parse(aSize[0]); ginfo.pxHeight = Byte.Parse(aSize[1]); ginfo.pxAdvanceWidth = Byte.Parse(strAW); ginfo.pxLeftSideBearing = SByte.Parse(strLSB); ginfo.nFlags = 0; ginfo.nFlags |= (strForceWhite == "true" ? MyGlyphFlags.ForceWhite : MyGlyphFlags.None); m_dictUnicode2GlyphInfo[strChar[0]] = ginfo; } } }