Unstable 0.16.0.0
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using SharpFont;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -130,7 +132,7 @@ namespace Barotrauma
|
||||
/// <param name="charRanges">Character ranges between each even element with their corresponding odd element. Default is 0x20 to 0xFFFF.</param>
|
||||
/// <param name="texDims">Texture dimensions. Default is 512x512.</param>
|
||||
/// <param name="baseChar">Base character used to shift all other characters downwards when rendering. Defaults to T.</param>
|
||||
public void RenderAtlas(GraphicsDevice gd, uint[] charRanges = null, int texDims = 1024, uint baseChar = 0x54)
|
||||
private void RenderAtlas(GraphicsDevice gd, uint[] charRanges = null, int texDims = 1024, uint baseChar = 0x54)
|
||||
{
|
||||
if (DynamicLoading) { return; }
|
||||
|
||||
@@ -253,13 +255,19 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void DynamicRenderAtlas(GraphicsDevice gd, uint character, int texDims = 1024, uint baseChar = 0x54)
|
||||
private void DynamicRenderAtlas(GraphicsDevice gd, uint character, int texDims = 1024, uint baseChar = 0x54)
|
||||
=> DynamicRenderAtlas(gd, character.ToEnumerable(), texDims, baseChar);
|
||||
|
||||
private void DynamicRenderAtlas(GraphicsDevice gd, string str, int texDims = 1024, uint baseChar = 0x54)
|
||||
=> DynamicRenderAtlas(gd, str.Distinct().Select(c => (uint)c), texDims, baseChar);
|
||||
|
||||
private void DynamicRenderAtlas(GraphicsDevice gd, IEnumerable<uint> characters, int texDims = 1024, uint baseChar = 0x54)
|
||||
{
|
||||
if (System.Threading.Thread.CurrentThread != GameMain.MainThread)
|
||||
{
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
DynamicRenderAtlas(gd, character, texDims, baseChar);
|
||||
DynamicRenderAtlas(gd, characters, texDims, baseChar);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -271,7 +279,6 @@ namespace Barotrauma
|
||||
|
||||
lock (mutex)
|
||||
{
|
||||
if (texCoords.ContainsKey(character)) { return; }
|
||||
if (textures.Count == 0)
|
||||
{
|
||||
this.texDims = texDims;
|
||||
@@ -282,79 +289,90 @@ namespace Barotrauma
|
||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||
}
|
||||
|
||||
uint glyphIndex = face.GetCharIndex(character);
|
||||
if (glyphIndex == 0) { return; }
|
||||
|
||||
face.SetPixelSizes(0, size);
|
||||
face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
|
||||
if (face.Glyph.Metrics.Width == 0 || face.Glyph.Metrics.Height == 0)
|
||||
bool anyChanges = false;
|
||||
bool firstChar = true;
|
||||
foreach (var character in characters)
|
||||
{
|
||||
if (face.Glyph.Metrics.HorizontalAdvance > 0)
|
||||
if (texCoords.ContainsKey(character)) { continue; }
|
||||
|
||||
uint glyphIndex = face.GetCharIndex(character);
|
||||
if (glyphIndex == 0) { continue; }
|
||||
|
||||
face.SetPixelSizes(0, size);
|
||||
face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
|
||||
if (face.Glyph.Metrics.Width == 0 || face.Glyph.Metrics.Height == 0)
|
||||
{
|
||||
//glyph is empty, but char still applies advance
|
||||
GlyphData blankData = new GlyphData(
|
||||
advance: (float)face.Glyph.Metrics.HorizontalAdvance,
|
||||
texIndex: -1); //indicates no texture because the glyph is empty
|
||||
texCoords.Add(character, blankData);
|
||||
if (face.Glyph.Metrics.HorizontalAdvance > 0)
|
||||
{
|
||||
//glyph is empty, but char still applies advance
|
||||
GlyphData blankData = new GlyphData(
|
||||
advance: (float)face.Glyph.Metrics.HorizontalAdvance,
|
||||
texIndex: -1); //indicates no texture because the glyph is empty
|
||||
texCoords.Add(character, blankData);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//stacktrace doesn't really work that well when RenderGlyph throws an exception
|
||||
face.Glyph.RenderGlyph(RenderMode.Normal);
|
||||
bitmap = (byte[])face.Glyph.Bitmap.BufferData.Clone();
|
||||
glyphWidth = face.Glyph.Bitmap.Width;
|
||||
glyphHeight = bitmap.Length / glyphWidth;
|
||||
horizontalAdvance = face.Glyph.Metrics.HorizontalAdvance;
|
||||
drawOffset = new Vector2(face.Glyph.BitmapLeft, baseHeight * 14 / 10 - face.Glyph.BitmapTop);
|
||||
|
||||
if (glyphWidth > texDims - 1 || glyphHeight > texDims - 1)
|
||||
{
|
||||
throw new Exception(filename + ", " + size.ToString() + ", " + (char)character + "; Glyph dimensions exceed texture atlas dimensions");
|
||||
}
|
||||
|
||||
currentDynamicAtlasNextY = Math.Max(currentDynamicAtlasNextY, glyphHeight + 2);
|
||||
if (currentDynamicAtlasCoords.X + glyphWidth + 2 > texDims - 1)
|
||||
{
|
||||
currentDynamicAtlasCoords.X = 0;
|
||||
currentDynamicAtlasCoords.Y += currentDynamicAtlasNextY;
|
||||
currentDynamicAtlasNextY = 0;
|
||||
}
|
||||
//no more room in current texture atlas, create a new one
|
||||
if (currentDynamicAtlasCoords.Y + glyphHeight + 2 > texDims - 1)
|
||||
{
|
||||
currentDynamicAtlasCoords.X = 0;
|
||||
currentDynamicAtlasCoords.Y = 0;
|
||||
currentDynamicAtlasNextY = 0;
|
||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||
currentDynamicPixelBuffer = null;
|
||||
}
|
||||
//stacktrace doesn't really work that well when RenderGlyph throws an exception
|
||||
face.Glyph.RenderGlyph(RenderMode.Normal);
|
||||
bitmap = (byte[])face.Glyph.Bitmap.BufferData.Clone();
|
||||
glyphWidth = face.Glyph.Bitmap.Width;
|
||||
glyphHeight = bitmap.Length / glyphWidth;
|
||||
horizontalAdvance = face.Glyph.Metrics.HorizontalAdvance;
|
||||
drawOffset = new Vector2(face.Glyph.BitmapLeft, baseHeight * 14 / 10 - face.Glyph.BitmapTop);
|
||||
|
||||
GlyphData newData = new GlyphData(
|
||||
advance: (float)horizontalAdvance,
|
||||
texIndex: textures.Count - 1,
|
||||
texCoords: new Rectangle((int)currentDynamicAtlasCoords.X, (int)currentDynamicAtlasCoords.Y, glyphWidth, glyphHeight),
|
||||
drawOffset: drawOffset
|
||||
);
|
||||
texCoords.Add(character, newData);
|
||||
|
||||
if (currentDynamicPixelBuffer == null)
|
||||
{
|
||||
currentDynamicPixelBuffer = new uint[texDims * texDims];
|
||||
textures[newData.TexIndex].GetData<uint>(currentDynamicPixelBuffer, 0, texDims * texDims);
|
||||
}
|
||||
|
||||
for (int y = 0; y < glyphHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < glyphWidth; x++)
|
||||
if (glyphWidth > texDims - 1 || glyphHeight > texDims - 1)
|
||||
{
|
||||
byte byteColor = bitmap[x + y * glyphWidth];
|
||||
currentDynamicPixelBuffer[((int)currentDynamicAtlasCoords.X + x) + ((int)currentDynamicAtlasCoords.Y + y) * texDims] = (uint)(byteColor << 24 | 0x00ffffff);
|
||||
throw new Exception(filename + ", " + size.ToString() + ", " + (char)character + "; Glyph dimensions exceed texture atlas dimensions");
|
||||
}
|
||||
}
|
||||
textures[newData.TexIndex].SetData<uint>(currentDynamicPixelBuffer);
|
||||
|
||||
currentDynamicAtlasCoords.X += glyphWidth + 2;
|
||||
currentDynamicAtlasNextY = Math.Max(currentDynamicAtlasNextY, glyphHeight + 2);
|
||||
if (currentDynamicAtlasCoords.X + glyphWidth + 2 > texDims - 1)
|
||||
{
|
||||
currentDynamicAtlasCoords.X = 0;
|
||||
currentDynamicAtlasCoords.Y += currentDynamicAtlasNextY;
|
||||
currentDynamicAtlasNextY = 0;
|
||||
}
|
||||
//no more room in current texture atlas, create a new one
|
||||
if (currentDynamicAtlasCoords.Y + glyphHeight + 2 > texDims - 1)
|
||||
{
|
||||
if (!firstChar) { textures[^1].SetData<uint>(currentDynamicPixelBuffer); }
|
||||
currentDynamicAtlasCoords.X = 0;
|
||||
currentDynamicAtlasCoords.Y = 0;
|
||||
currentDynamicAtlasNextY = 0;
|
||||
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
|
||||
currentDynamicPixelBuffer = null;
|
||||
}
|
||||
|
||||
GlyphData newData = new GlyphData(
|
||||
advance: (float)horizontalAdvance,
|
||||
texIndex: textures.Count - 1,
|
||||
texCoords: new Rectangle((int)currentDynamicAtlasCoords.X, (int)currentDynamicAtlasCoords.Y, glyphWidth, glyphHeight),
|
||||
drawOffset: drawOffset
|
||||
);
|
||||
texCoords.Add(character, newData);
|
||||
|
||||
if (currentDynamicPixelBuffer == null)
|
||||
{
|
||||
currentDynamicPixelBuffer = new uint[texDims * texDims];
|
||||
textures[newData.TexIndex].GetData<uint>(currentDynamicPixelBuffer, 0, texDims * texDims);
|
||||
}
|
||||
|
||||
for (int y = 0; y < glyphHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < glyphWidth; x++)
|
||||
{
|
||||
byte byteColor = bitmap[x + y * glyphWidth];
|
||||
currentDynamicPixelBuffer[((int)currentDynamicAtlasCoords.X + x) + ((int)currentDynamicAtlasCoords.Y + y) * texDims] = (uint)(byteColor << 24 | 0x00ffffff);
|
||||
}
|
||||
}
|
||||
|
||||
currentDynamicAtlasCoords.X += glyphWidth + 2;
|
||||
firstChar = false;
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
if (anyChanges) { textures[^1].SetData<uint>(currentDynamicPixelBuffer); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,6 +392,10 @@ namespace Barotrauma
|
||||
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth)
|
||||
{
|
||||
if (textures.Count == 0 && !DynamicLoading) { return; }
|
||||
if (DynamicLoading)
|
||||
{
|
||||
DynamicRenderAtlas(graphicsDevice, text);
|
||||
}
|
||||
|
||||
int lineNum = 0;
|
||||
Vector2 currentPos = position;
|
||||
@@ -390,10 +412,6 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
uint charIndex = text[i];
|
||||
if (DynamicLoading)
|
||||
{
|
||||
DynamicRenderAtlas(graphicsDevice, charIndex);
|
||||
}
|
||||
|
||||
GlyphData gd = GetGlyphData(charIndex);
|
||||
if (gd.TexIndex >= 0)
|
||||
@@ -417,6 +435,10 @@ namespace Barotrauma
|
||||
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color)
|
||||
{
|
||||
if (textures.Count == 0 && !DynamicLoading) { return; }
|
||||
if (DynamicLoading)
|
||||
{
|
||||
DynamicRenderAtlas(graphicsDevice, text);
|
||||
}
|
||||
|
||||
Vector2 currentPos = position;
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
@@ -429,10 +451,6 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
uint charIndex = text[i];
|
||||
if (DynamicLoading)
|
||||
{
|
||||
DynamicRenderAtlas(graphicsDevice, charIndex);
|
||||
}
|
||||
|
||||
GlyphData gd = GetGlyphData(charIndex);
|
||||
if (gd.TexIndex >= 0)
|
||||
@@ -452,6 +470,10 @@ namespace Barotrauma
|
||||
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth, List<RichTextData> richTextData, int rtdOffset = 0)
|
||||
{
|
||||
if (textures.Count == 0 && !DynamicLoading) { return; }
|
||||
if (DynamicLoading)
|
||||
{
|
||||
DynamicRenderAtlas(graphicsDevice, text);
|
||||
}
|
||||
|
||||
int lineNum = 0;
|
||||
Vector2 currentPos = position;
|
||||
@@ -472,10 +494,6 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
uint charIndex = text[i];
|
||||
if (DynamicLoading && !texCoords.ContainsKey(charIndex))
|
||||
{
|
||||
DynamicRenderAtlas(graphicsDevice, charIndex);
|
||||
}
|
||||
|
||||
Color currentTextColor;
|
||||
|
||||
@@ -626,6 +644,10 @@ namespace Barotrauma
|
||||
{
|
||||
retVal.Y = baseHeight;
|
||||
}
|
||||
if (DynamicLoading)
|
||||
{
|
||||
DynamicRenderAtlas(graphicsDevice, text);
|
||||
}
|
||||
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
@@ -636,10 +658,6 @@ namespace Barotrauma
|
||||
continue;
|
||||
}
|
||||
uint charIndex = text[i];
|
||||
if (DynamicLoading && !texCoords.ContainsKey(charIndex))
|
||||
{
|
||||
DynamicRenderAtlas(graphicsDevice, charIndex);
|
||||
}
|
||||
|
||||
GlyphData gd = GetGlyphData(charIndex);
|
||||
currentLineX += gd.Advance;
|
||||
|
||||
Reference in New Issue
Block a user