public void PrintText(BitmapFont font, string text, float x, float y, Color4 color, float rotation = 0.0f, float scale = 1.0f, float xOrigin = 0.0f, float yOrigin = 0.0f, bool flipHorizontally = false, bool flipVertically = false) { if (font == null) throw new ArgumentException("font"); SizeF size = font.Measure(text); Matrix4 trans = Matrix4.Identity * Matrix4.CreateRotationZ(rotation) * Matrix4.Scale(scale) * Matrix4.CreateTranslation(x, y, 0.0f); float xOffset = 0f; float yOffset = 0f; text = text.Replace("\r\n", "\r"); xOffset -= (int)(xOrigin * font.MeasureNextlineLength(text)); yOffset -= (int)(yOrigin * size.Height); for (int i = 0; i < text.Length; i++) { char c = text[i]; //newline if (c == '\r' || c == '\n') { yOffset += font.LineSpacing; xOffset = 0f; xOffset -= (int)(xOrigin * font.MeasureNextlineLength(text.Substring(i + 1))); } else { //normal character if (c != ' ' && font.fontData.CharSetMapping.ContainsKey(c)) RenderGlyph(font, c, x, y, xOffset, yOffset, color,rotation, scale, flipHorizontally, flipVertically); if (font.IsMonospacingActive) xOffset += font.MonoSpaceWidth; else { if (c == ' ') xOffset += (float)Math.Ceiling(font.fontData.meanGlyphWidth * font.Options.WordSpacing); //normal character else if (font.fontData.CharSetMapping.ContainsKey(c)) { FontGlyph glyph = font.fontData.CharSetMapping[c]; xOffset += (float)Math.Ceiling(glyph.rect.Width + font.fontData.meanGlyphWidth * font.Options.CharacterSpacing + font.fontData.GetKerningPairCorrection(i, text, null)); } } } } }
//This overload allows justification, but it is quite slow.. maybe) Recomended for use only in case, when justification is necessary public void PrintText(BitmapFont font, string text, float x, float y, float width, bool justify, Color4 color, float rotation = 0.0f, float scale = 1.0f, float xOrigin = 0.5f, float yOrigin = 0.5f, bool flipHorizontally = false, bool flipVertically = false) { if (font == null) throw new ArgumentException("font"); float maxMeasuredWidth = 0f; ProcessedText processedText = font.ProcessText(text, width, justify); float maxWidth = processedText.maxWidth; float xOffset = 0f; float yOffset = 0f; SizeF size = font.Measure(processedText); var nodeList = processedText.textNodeList; for (TextNode node = nodeList.Head; node != null; node = node.Next) node.LengthTweak = 0f; //reset tweaks yOffset -= yOrigin * size.Height; if (justify) { font.JustifyLine(nodeList.Head, maxWidth); xOffset -= (int)(xOrigin * maxWidth); } else xOffset -= (float)Math.Ceiling(xOrigin * font.TextNodeLineLength(nodeList.Head, maxWidth)); bool atLeastOneNodeCosumedOnLine = false; float length = 0f; for (TextNode node = nodeList.Head; node != null; node = node.Next) { bool newLine = false; if (node.Type == TextNodeType.LineBreak) { newLine = true; } else { if (font.SkipTrailingSpace(node, length, maxWidth) && atLeastOneNodeCosumedOnLine) { newLine = true; } else if (length + node.ModifiedLength <= maxWidth || !atLeastOneNodeCosumedOnLine) { atLeastOneNodeCosumedOnLine = true; RenderWord(font, node, x, y, xOffset + length, yOffset, color, rotation, scale, flipHorizontally, flipVertically); length += node.ModifiedLength; maxMeasuredWidth = Math.Max(length, maxMeasuredWidth); } else { newLine = true; if (node.Previous != null) node = node.Previous; } } if (newLine) { yOffset += font.LineSpacing; xOffset = 0f; length = 0f; atLeastOneNodeCosumedOnLine = false; if (node.Next != null) { if (justify) { font.JustifyLine(node.Next, maxWidth); xOffset -= (int)(xOrigin * maxWidth); } else xOffset -= (float)Math.Ceiling(xOrigin * font.TextNodeLineLength(node.Next, maxWidth)); } } } }