Unstable v0.19.5.0

This commit is contained in:
Juan Pablo Arce
2022-09-14 12:47:17 -03:00
parent 3f2c843247
commit 1fd2a51bbb
158 changed files with 5702 additions and 4813 deletions
@@ -6,23 +6,26 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Xml.Linq;
using System.Threading;
using Barotrauma.Threading;
namespace Barotrauma
{
public class ScalableFont : IDisposable
{
private static List<ScalableFont> FontList = new List<ScalableFont>();
private static readonly List<ScalableFont> FontList = new List<ScalableFont>();
private static Library Lib = null;
private readonly object mutex = new object();
private static readonly object globalMutex = new object();
private readonly ReaderWriterLockSlim rwl = new ReaderWriterLockSlim();
private string filename;
private Face face;
private readonly string filename;
private readonly Face face;
private uint size;
private int baseHeight;
private Dictionary<uint, GlyphData> texCoords;
private List<Texture2D> textures;
private GraphicsDevice graphicsDevice;
private readonly Dictionary<uint, GlyphData> texCoords;
private readonly List<Texture2D> textures;
private readonly GraphicsDevice graphicsDevice;
private Vector2 currentDynamicAtlasCoords;
private int currentDynamicAtlasNextY;
@@ -49,7 +52,7 @@ namespace Barotrauma
set
{
size = value;
if (graphicsDevice != null) RenderAtlas(graphicsDevice, charRanges, texDims, baseChar);
if (graphicsDevice != null) { RenderAtlas(graphicsDevice, charRanges, texDims, baseChar); }
}
}
@@ -93,11 +96,15 @@ namespace Barotrauma
public ScalableFont(string filename, uint size, GraphicsDevice gd = null, bool dynamicLoading = false, bool isCJK = false)
{
lock (mutex)
lock (globalMutex)
{
Lib ??= new Library();
}
this.filename = filename;
this.face = null;
using (new ReadLock(rwl))
{
if (Lib == null) Lib = new Library();
this.filename = filename;
this.face = null;
foreach (ScalableFont font in FontList)
{
if (font.filename == filename)
@@ -106,19 +113,23 @@ namespace Barotrauma
break;
}
}
this.face ??= new Face(Lib, filename);
this.size = size;
this.textures = new List<Texture2D>();
this.texCoords = new Dictionary<uint, GlyphData>();
this.DynamicLoading = dynamicLoading;
this.IsCJK = isCJK;
this.graphicsDevice = gd;
}
if (gd != null && !dynamicLoading)
{
RenderAtlas(gd);
}
this.face ??= new Face(Lib, filename);
this.size = size;
this.textures = new List<Texture2D>();
this.texCoords = new Dictionary<uint, GlyphData>();
this.DynamicLoading = dynamicLoading;
this.IsCJK = isCJK;
this.graphicsDevice = gd;
if (gd != null && !dynamicLoading)
{
RenderAtlas(gd);
}
lock (globalMutex)
{
FontList.Add(this);
}
}
@@ -162,7 +173,7 @@ namespace Barotrauma
Vector2 currentCoords = Vector2.Zero;
int nextY = 0;
lock (mutex)
using (new WriteLock(rwl))
{
face.SetPixelSizes(0, size);
face.LoadGlyph(face.GetCharIndex(baseChar), LoadFlags.Default, LoadTarget.Normal);
@@ -175,19 +186,22 @@ namespace Barotrauma
for (uint j = start; j <= end; j++)
{
uint glyphIndex = face.GetCharIndex(j);
if (glyphIndex == 0) continue;
if (glyphIndex == 0)
{
texCoords.Add(j, new GlyphData(
advance: 0,
texIndex: -1));
continue;
}
face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
if (face.Glyph.Metrics.Width == 0 || face.Glyph.Metrics.Height == 0)
{
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
//glyph is empty, but char might still apply advance
GlyphData blankData = new GlyphData(
advance: Math.Max((float)face.Glyph.Metrics.HorizontalAdvance, 0f),
texIndex: -1); //indicates no texture because the glyph is empty
texCoords.Add(j, blankData);
}
texCoords.Add(j, blankData);
continue;
}
//stacktrace doesn't really work that well when RenderGlyph throws an exception
@@ -257,7 +271,7 @@ namespace Barotrauma
private void DynamicRenderAtlas(GraphicsDevice gd, uint character, int texDims = 1024, uint baseChar = 0x54)
{
bool missingCharacterFound = false;
lock (mutex)
using (new ReadLock(rwl))
{
missingCharacterFound = !texCoords.ContainsKey(character);
}
@@ -268,10 +282,9 @@ namespace Barotrauma
private void DynamicRenderAtlas(GraphicsDevice gd, string str, int texDims = 1024, uint baseChar = 0x54)
{
bool missingCharacterFound = false;
var distinctChrs = str.Distinct().Select(c => (uint)c).ToArray();
lock (mutex)
using (new ReadLock(rwl))
{
foreach (var character in distinctChrs)
foreach (var character in str)
{
if (texCoords.ContainsKey(character)) { continue; }
@@ -280,7 +293,7 @@ namespace Barotrauma
}
}
if (!missingCharacterFound) { return; }
DynamicRenderAtlas(gd, distinctChrs, texDims, baseChar);
DynamicRenderAtlas(gd, str.Select(c => (uint)c), texDims, baseChar);
}
private void DynamicRenderAtlas(GraphicsDevice gd, IEnumerable<uint> characters, int texDims = 1024, uint baseChar = 0x54)
@@ -299,7 +312,7 @@ namespace Barotrauma
Fixed26Dot6 horizontalAdvance;
Vector2 drawOffset;
lock (mutex)
using (new WriteLock(rwl))
{
if (textures.Count == 0)
{
@@ -318,20 +331,23 @@ namespace Barotrauma
if (texCoords.ContainsKey(character)) { continue; }
uint glyphIndex = face.GetCharIndex(character);
if (glyphIndex == 0) { continue; }
if (glyphIndex == 0)
{
texCoords.Add(character, new GlyphData(
advance: 0,
texIndex: -1));
continue;
}
face.SetPixelSizes(0, size);
face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
if (face.Glyph.Metrics.Width == 0 || face.Glyph.Metrics.Height == 0)
{
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);
}
//glyph is empty, but char might still apply advance
GlyphData blankData = new GlyphData(
advance: Math.Max((float)face.Glyph.Metrics.HorizontalAdvance, 0f),
texIndex: -1); //indicates no texture because the glyph is empty
texCoords.Add(character, blankData);
continue;
}