Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // smart text drawing
- // text = the text to draw
- // bounds = the box where the text will be drawn
- // spritebatch = the spritebatch
- // font = the font
- // cutoff = the point (character) where the text stops drawing (doesn't effect allignment)
- // allignmentX = the allignment in which the text will be drawn (X
- // allignmentY = the allignment in which the text will be drawn (Y)
- // paddingX = padding between lines and the edge of the bounds (X)
- // paddingY = padding between lines and the edge of the bounds (Y)
- // measureOnly = whether or not to actually draw text or just measure the size the text would take (easier not to enable manually, just use helper function below)
- // TODO character / word that forces new line or to stop displaying until interacted with
- public static Point smartDrawText(string text, Rectangle bounds, SpriteBatch spriteBatch, SpriteFont font, Color color, int cutoff = 0, allignX allignmentX = allignX.LEFT, allignY allignmentY = allignY.TOP, int paddingX = 2, int paddingY = 2, bool measureOnly = false) {
- string[] words = text.Split(' '); // array of the words in text
- float textHeight = font.MeasureString(text).Y;
- float yProgress = 0;
- // calculate cutoff point
- int tempCounter = 0;
- int displayedWords = 0;
- int finalWordCutoff = 0;
- foreach (string w in words) {
- if (tempCounter + w.Length + 1 <= cutoff) {
- tempCounter += w.Length + 1;
- }
- else if (tempCounter + w.Length <= cutoff) {
- tempCounter += w.Length;
- }
- else {
- finalWordCutoff = cutoff - tempCounter;
- break;
- }
- displayedWords++;
- }
- // store lines
- List<string> lines = new List<string>();
- List<Vector2> lineLocations = new List<Vector2>();
- // loop through lines
- int word = 0;
- while (word < words.Count()) {
- // construct text for each line
- string line = "";
- float lineWidth = paddingX;
- while (lineWidth <= bounds.Width - paddingX & word < words.Count()) {
- float newLineWidth = lineWidth + font.MeasureString(words[word] + " ").X;
- if (newLineWidth <= bounds.Width) {
- if (word < displayedWords || cutoff == 0) {
- line = line + words[word] + ' ';
- }
- else if (word == displayedWords) {
- line = line + words[word].Substring(0, finalWordCutoff);
- }
- lineWidth = newLineWidth + 1;
- word++;
- }
- else {
- break;
- }
- }
- // add x allignment
- Vector2 offsetX = new Vector2(paddingX, yProgress);
- float spaceLeftX = bounds.Width - lineWidth - paddingX * 2;
- switch (allignmentX) {
- case allignX.LEFT:
- break;
- case allignX.CENTER:
- offsetX = new Vector2(spaceLeftX / 2, offsetX.Y);
- break;
- case allignX.RIGHT:
- offsetX = new Vector2(spaceLeftX, offsetX.Y);
- break;
- }
- lines.Add(line); lineLocations.Add(new Vector2(bounds.X + offsetX.X, bounds.Y + offsetX.Y));
- // add to progress on y axis
- yProgress += textHeight + 2;
- }
- // get size of "text chunk"
- // if only measuring, just return size
- Point size = new Point(bounds.Width, (int)yProgress);
- if (measureOnly) return size;
- // add y allignment
- // yProgress now represents the height of the "chunk of text"
- float spaceLeftY = bounds.Height - yProgress - paddingY * 4;
- Vector2 offsetY = new Vector2(0, spaceLeftY + paddingY);
- switch (allignmentY) {
- case allignY.TOP:
- break;
- case allignY.CENTER:
- offsetY = new Vector2(0, offsetY.Y / 2);
- break;
- case allignY.BOTTOM:
- offsetY = new Vector2(0, offsetY.Y);
- break;
- }
- // finally draw all lines with proper x and y allignment options applied
- for (int counter = 0; counter < lines.Count; counter++) {
- spriteBatch.DrawString(font, lines.ElementAt(counter), new Vector2(lineLocations.ElementAt(counter).X, lineLocations.ElementAt(counter).Y + offsetY.Y), color, 0, new Vector2(), 1, SpriteEffects.None, 0.0009F);
- spriteBatch.DrawString(font, lines.ElementAt(counter), new Vector2(lineLocations.ElementAt(counter).X + 2, lineLocations.ElementAt(counter).Y + offsetY.Y + 2), Color.Black * 0.8F, 0, new Vector2(), 1, SpriteEffects.None, 0.00091F);
- }
- return size;
- }
- public static Point measureText(string text, Rectangle bounds, SpriteFont font) {
- return smartDrawText(text, bounds, null, font, Color.White, 0, allignX.LEFT, allignY.TOP, 2, 2, true);
- }
Advertisement
Add Comment
Please, Sign In to add comment