/** * ParseText * * Parse the text to render, accounting for tagged values (superscript, subscript, font, nudge, etc). */ private void ParseText(string textToRender, int screenXMin, int screenYMin, Color defaultColor, int pageFont) { if (pageFont >= fontRenderer.Count) { pageFont = 0; } float yCursor = screenYMin * fontLetterHeight; Color fontColor = defaultColor; float xOffset = 0.0f; float yOffset = 0.0f; Script scriptType = Script.Normal; Width fontWidth = Width.Normal; FontRenderer fr = fontRenderer[pageFont]; bool anyWarnings = false; float xCursor = screenXMin * fontLetterWidth; for (int charIndex = 0; charIndex < textToRender.Length; charIndex++) { bool escapedBracket = false; // We will continue parsing bracket pairs until we're out of bracket pairs, // since all of them -- except the escaped bracket tag -- // consume characters and change state without actually generating any output. while (charIndex < textToRender.Length && textToRender[charIndex] == '[') { // If there's no closing bracket, we stop parsing and go on to printing. int nextBracket = textToRender.IndexOf(']', charIndex) - charIndex; if (nextBracket < 1) { break; } // Much easier to parse it this way, although I suppose more expensive. string tagText = textToRender.Substring(charIndex + 1, nextBracket - 1); if ((tagText.Length == 9 || tagText.Length == 7) && tagText[0] == '#') { // Valid color tags are [#rrggbbaa] or [#rrggbb]. fontColor = JUtil.HexRGBAToColor(tagText.Substring(1)); charIndex += nextBracket + 1; } else if (tagText.Length > 2 && tagText[0] == '@') { // Valid nudge tags are [@x<number>] or [@y<number>] so the conditions for them is that // the next symbol is @ and there are at least three, one designating the axis. float coord; if (float.TryParse(tagText.Substring(2), out coord)) { switch (tagText[1]) { case 'X': case 'x': xOffset = coord; break; case 'Y': case 'y': yOffset = coord; break; } // We only consume the symbols if they did parse correctly. charIndex += nextBracket + 1; } else //If it didn't parse, skip over it. { break; } } else if (tagText == "sup") { // Superscript! scriptType = Script.Superscript; charIndex += nextBracket + 1; } else if (tagText == "sub") { // Subscript! scriptType = Script.Subscript; charIndex += nextBracket + 1; } else if (tagText == "/sup" || tagText == "/sub") { // And back... scriptType = Script.Normal; charIndex += nextBracket + 1; } else if (tagText == "hw") { fontWidth = Width.Half; charIndex += nextBracket + 1; } else if (tagText == "dw") { fontWidth = Width.Double; charIndex += nextBracket + 1; } else if (tagText == "/hw" || tagText == "/dw") { // And back... fontWidth = Width.Normal; charIndex += nextBracket + 1; } else if (tagText.StartsWith("font", StringComparison.Ordinal)) { int newFontID; if (int.TryParse(tagText.Substring(4), out newFontID) && newFontID >= 0 && newFontID < fontRenderer.Count) { //fontTextureIndex = (int)newFontID; fr = fontRenderer[newFontID]; } charIndex += nextBracket + 1; } else if (tagText == "[") { // We got a "[[]" which means an escaped opening bracket. escapedBracket = true; charIndex += nextBracket; break; } else // Else we didn't recognise anything so it's not a tag. { break; } } if (string.Compare(textToRender, charIndex, Environment.NewLine, 0, Environment.NewLine.Length) == 0) { // New line: Advance yCursor, reset xCursor and the various state values. yCursor += fontLetterHeight; xCursor = screenXMin * fontLetterWidth; charIndex += Environment.NewLine.Length - 1; fontColor = defaultColor; xOffset = 0.0f; yOffset = 0.0f; fontWidth = Width.Normal; scriptType = Script.Normal; fr = fontRenderer[pageFont]; } else { float xPos = xCursor + xOffset; float yPos = yCursor + yOffset; if (charIndex < textToRender.Length && xPos < screenPixelWidth && xPos > -(fontWidth == Width.Normal ? fontLetterWidth : (fontWidth == Width.Half ? fontLetterHalfWidth : fontLetterDoubleWidth)) && yPos < screenPixelHeight && yPos > -fontLetterHeight) { if (!DrawChar(fr, escapedBracket ? '[' : textToRender[charIndex], xPos, yPos, fontColor, scriptType, fontWidth)) { anyWarnings = true; } } switch (fontWidth) { case Width.Normal: xCursor += fontLetterWidth; break; case Width.Half: xCursor += fontLetterHalfWidth; break; case Width.Double: xCursor += fontLetterDoubleWidth; break; } } } if (anyWarnings) { JUtil.LogMessage(this, "String missing characters: {0}", textToRender); } }
private void RenderText(string[] textBuffer, bool drawingOverlay = false) { float yCursor = drawingOverlay ? 0 : (activePage.screenYMin * fontLetterHeight); for (int lineIndex = 0; lineIndex < textBuffer.Length; yCursor += fontLetterHeight, lineIndex++) { if (!string.IsNullOrEmpty(textBuffer[lineIndex])) { Color fontColor = activePage.defaultColor; float xOffset = 0; float yOffset = 0; Script scriptType = Script.Normal; Width fontWidth = Width.Normal; fontTextureIndex = 0; if (activePage.pageFont < fontTexture.Count) { fontTextureIndex = activePage.pageFont; } float xCursor = drawingOverlay ? 0 : (activePage.screenXMin * fontLetterWidth); for (int charIndex = 0; charIndex < textBuffer[lineIndex].Length; charIndex++) { bool escapedBracket = false; // We will continue parsing bracket pairs until we're out of bracket pairs, // since all of them -- except the escaped bracket tag -- // consume characters and change state without actually generating any output. while (charIndex < textBuffer[lineIndex].Length && textBuffer[lineIndex][charIndex] == '[') { // If there's no closing bracket, we stop parsing and go on to printing. int nextBracket = textBuffer[lineIndex].IndexOf(']', charIndex) - charIndex; if (nextBracket < 1) { break; } // Much easier to parse it this way, although I suppose more expensive. string tagText = textBuffer[lineIndex].Substring(charIndex + 1, nextBracket - 1); if ((tagText.Length == 9 || tagText.Length == 7) && tagText[0] == '#') { // Valid color tags are [#rrggbbaa] or [#rrggbb]. fontColor = JUtil.HexRGBAToColor(tagText.Substring(1)); charIndex += nextBracket + 1; } else if (tagText.Length > 2 && tagText[0] == '@') { // Valid nudge tags are [@x<number>] or [@y<number>] so the conditions for them is that // the next symbol is @ and there are at least three, one designating the axis. float coord; if (float.TryParse(tagText.Substring(2), out coord)) { switch (tagText[1]) { case 'X': case 'x': xOffset = coord; break; case 'Y': case 'y': yOffset = coord; break; } // We only consume the symbols if they did parse correctly. charIndex += nextBracket + 1; } else //If it didn't parse, skip over it. { break; } } else if (tagText == "sup") { // Superscript! scriptType = Script.Superscript; charIndex += nextBracket + 1; } else if (tagText == "sub") { // Subscript! scriptType = Script.Subscript; charIndex += nextBracket + 1; } else if (tagText == "/sup" || tagText == "/sub") { // And back... scriptType = Script.Normal; charIndex += nextBracket + 1; } else if (tagText == "hw") { fontWidth = Width.Half; charIndex += nextBracket + 1; } else if (tagText == "dw") { fontWidth = Width.Double; charIndex += nextBracket + 1; } else if (tagText == "/hw" || tagText == "/dw") { // And back... fontWidth = Width.Normal; charIndex += nextBracket + 1; } else if (tagText.StartsWith("font", StringComparison.Ordinal)) { uint newFontID; if (uint.TryParse(tagText.Substring(4), out newFontID) && newFontID < fontTexture.Count) { fontTextureIndex = (int)newFontID; } charIndex += nextBracket + 1; } else if (tagText == "[") { // We got a "[[]" which means an escaped opening bracket. escapedBracket = true; charIndex += nextBracket; break; } else // Else we didn't recognise anything so it's not a tag. { break; } } float xPos = xCursor + xOffset; float yPos = yCursor + yOffset; if (charIndex < textBuffer[lineIndex].Length && xPos <screenPixelWidth && xPos> -(fontWidth == Width.Normal ? fontLetterWidth : (fontWidth == Width.Half ? fontLetterHalfWidth : fontLetterDoubleWidth)) && yPos <screenPixelHeight && yPos> -fontLetterHeight) { DrawChar(escapedBracket ? '[' : textBuffer[lineIndex][charIndex], xPos, yPos, fontColor, scriptType, fontWidth); } switch (fontWidth) { case Width.Normal: xCursor += fontLetterWidth; break; case Width.Half: xCursor += fontLetterHalfWidth; break; case Width.Double: xCursor += fontLetterDoubleWidth; break; } } } } }