Merge branch 'HydrogenC-master'

This commit is contained in:
Wojtek Figat
2024-02-18 19:48:56 +01:00
20 changed files with 165 additions and 57 deletions

1
.gitignore vendored
View File

@@ -11,7 +11,6 @@ Source/*.Gen.*
Source/*.csproj
/Package_*/
!Source/Engine/Debug
/Source/Platforms/Editor/Linux/Mono/etc/mono/registry
PackageEditor_Cert.command
PackageEditor_Cert.bat
PackagePlatforms_Cert.bat

Binary file not shown.

View File

@@ -54,6 +54,11 @@ namespace FlaxEditor
/// </summary>
public static string PrimaryFont = "Editor/Fonts/Roboto-Regular";
/// <summary>
/// The secondary (fallback) font to use for missing characters rendering (CJK - Chinese/Japanese/Korean characters).
/// </summary>
public static string FallbackFont = "Editor/Fonts/NotoSansSC-Regular";
/// <summary>
/// The Inconsolata Regular font.
/// </summary>

View File

@@ -43,8 +43,9 @@ namespace FlaxEditor.GUI
{
Depth = -1;
if (Height < Style.Current.FontMedium.Height)
Height = Style.Current.FontMedium.Height + 4;
var fontHeight = Style.Current.FontMedium.Height;
if (Height < fontHeight)
Height = fontHeight + 4;
}
/// <inheritdoc />

View File

@@ -172,9 +172,9 @@ namespace FlaxEditor.Options
set
{
if (value == null)
_outputLogFont = new FontReference(FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.InconsolataRegularFont), 10);
_outputLogFont = new FontReference(ConsoleFont, 10);
else if (!value.Font)
_outputLogFont.Font = FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.InconsolataRegularFont);
_outputLogFont.Font = ConsoleFont;
else
_outputLogFont = value;
}
@@ -237,11 +237,19 @@ namespace FlaxEditor.Options
public int NumberOfGameClientsToLaunch = 1;
private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.PrimaryFont);
private static FontAsset ConsoleFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.InconsolataRegularFont);
private FontReference _titleFont = new FontReference(DefaultFont, 18);
private FontReference _largeFont = new FontReference(DefaultFont, 14);
private FontReference _mediumFont = new FontReference(DefaultFont, 9);
private FontReference _smallFont = new FontReference(DefaultFont, 9);
private FontReference _outputLogFont = new FontReference(FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.InconsolataRegularFont), 10);
private FontReference _outputLogFont = new FontReference(ConsoleFont, 10);
/// <summary>
/// The list of fallback fonts to use when main text font is missing certain characters. Empty to use fonts from GraphicsSettings.
/// </summary>
[EditorDisplay("Fonts"), EditorOrder(650)]
public FontAsset[] FallbackFonts = [FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.FallbackFont)];
/// <summary>
/// Gets or sets the title font for editor UI.

View File

@@ -3,6 +3,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FlaxEditor.Content.Settings;
using FlaxEditor.Modules;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -217,12 +219,18 @@ namespace FlaxEditor.Options
if (styleName == ThemeOptions.LightDefault)
{
Style.Current = CreateLightStyle();
}
}
else
{
Style.Current = CreateDefaultStyle();
}
}
// Set fallback fonts
var fallbackFonts = Options.Interface.FallbackFonts;
if (fallbackFonts == null || fallbackFonts.Length == 0 || fallbackFonts.All(x => x == null))
fallbackFonts = GameSettings.Load<GraphicsSettings>().FallbackFonts;
Font.FallbackFonts = fallbackFonts;
}
/// <summary>

View File

@@ -144,7 +144,7 @@ namespace FlaxEditor.Windows.Assets
protected override void OnAssetLinked()
{
Asset.WaitForLoaded();
_textPreview.Font = new FontReference(Asset.CreateFont(30));
_textPreview.Font = new FontReference(Asset, 30);
_inputText.Text = string.Format("This is a sample text using font {0}.", Asset.FamilyName);
var options = Asset.Options;
_proxy.Set(ref options);

View File

@@ -119,7 +119,7 @@ namespace FlaxEditor.Content.Settings
/// <summary>
/// The custom settings to use with a game. Can be specified by the user to define game-specific options and be used by the external plugins (used as key-value pair).
/// </summary>
[EditorOrder(1100), EditorDisplay("Other Settings"), Tooltip("The custom settings to use with a game. Can be specified by the user to define game-specific options and be used by the external plugins (used as key-value pair).")]
[EditorOrder(1500), EditorDisplay("Other Settings"), Tooltip("The custom settings to use with a game. Can be specified by the user to define game-specific options and be used by the external plugins (used as key-value pair).")]
public Dictionary<string, JsonAsset> CustomSettings;
#if FLAX_EDITOR || PLATFORM_WINDOWS

View File

@@ -6,6 +6,8 @@
#include "Engine/Graphics/Enums.h"
#include "Engine/Graphics/PostProcessSettings.h"
class FontAsset;
/// <summary>
/// Graphics rendering settings.
/// </summary>
@@ -13,6 +15,7 @@ API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings", NoConstructor) class
{
API_AUTO_SERIALIZATION();
DECLARE_SCRIPTING_TYPE_MINIMAL(GraphicsSettings);
public:
/// <summary>
/// Enables rendering synchronization with the refresh rate of the display device to avoid "tearing" artifacts.
@@ -118,6 +121,12 @@ public:
API_FIELD(Attributes="EditorOrder(10000), EditorDisplay(\"Post Process Settings\", EditorDisplayAttribute.InlineStyle)")
PostProcessSettings PostProcessSettings;
/// <summary>
/// The list of fallback fonts used for text rendering. Ignored if empty.
/// </summary>
API_FIELD(Attributes="EditorOrder(5000), EditorDisplay(\"Text\")")
Array<AssetReference<FontAsset>> FallbackFonts;
private:
/// <summary>
/// Renamed UeeHDRProbes into UseHDRProbes

View File

@@ -8,6 +8,7 @@
#include "Engine/Core/Config/GraphicsSettings.h"
#include "Engine/Engine/CommandLine.h"
#include "Engine/Engine/EngineService.h"
#include "Engine/Render2D/Font.h"
bool Graphics::UseVSync = false;
Quality Graphics::AAQuality = Quality::Medium;
@@ -69,6 +70,9 @@ void GraphicsSettings::Apply()
Graphics::GIQuality = GIQuality;
Graphics::PostProcessSettings = ::PostProcessSettings();
Graphics::PostProcessSettings.BlendWith(PostProcessSettings, 1.0f);
#if !USE_EDITOR // OptionsModule handles fallback fonts in Editor
Font::FallbackFonts = FallbackFonts;
#endif
}
void Graphics::DisposeDevice()

View File

@@ -7,6 +7,8 @@
#include "Engine/Threading/Threading.h"
#include "IncludeFreeType.h"
Array<AssetReference<FontAsset>, HeapAllocation> Font::FallbackFonts;
Font::Font(FontAsset* parentAsset, float size)
: ManagedScriptingObject(SpawnParams(Guid::New(), Font::TypeInitializer))
, _asset(parentAsset)
@@ -32,7 +34,7 @@ Font::~Font()
_asset->_fonts.Remove(this);
}
void Font::GetCharacter(Char c, FontCharacterEntry& result)
void Font::GetCharacter(Char c, FontCharacterEntry& result, bool enableFallback)
{
// Try to get the character or cache it if cannot be found
if (!_characters.TryGet(c, result))
@@ -44,6 +46,20 @@ void Font::GetCharacter(Char c, FontCharacterEntry& result)
if (_characters.TryGet(c, result))
return;
// Try to use fallback font if character is missing
if (enableFallback && !_asset->ContainsChar(c))
{
for (int32 fallbackIndex = 0; fallbackIndex < FallbackFonts.Count(); fallbackIndex++)
{
FontAsset* fallbackFont = FallbackFonts.Get()[fallbackIndex].Get();
if (fallbackFont && fallbackFont->ContainsChar(c))
{
fallbackFont->CreateFont(GetSize())->GetCharacter(c, result, enableFallback);
return;
}
}
}
// Create character cache
FontManager::AddNewEntry(this, c, result);
@@ -87,7 +103,7 @@ void Font::CacheText(const StringView& text)
FontCharacterEntry entry;
for (int32 i = 0; i < text.Length(); i++)
{
GetCharacter(text[i], entry);
GetCharacter(text[i], entry, false);
}
}
@@ -104,12 +120,14 @@ void Font::Invalidate()
void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines, const TextLayoutOptions& layout)
{
int32 textLength = text.Length();
if (textLength == 0)
return;
float cursorX = 0;
int32 kerning;
FontLineCache tmpLine;
FontCharacterEntry entry;
FontCharacterEntry previous;
int32 textLength = text.Length();
float scale = layout.Scale / FontManager::FontScale;
float boundsWidth = layout.Bounds.GetWidth();
float baseLinesDistance = static_cast<float>(_height) * layout.BaseLinesGapScale * scale;
@@ -157,7 +175,7 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
// Get kerning
if (!isWhitespace && previous.IsValid)
{
kerning = GetKerning(previous.Character, entry.Character);
kerning = entry.Font->GetKerning(previous.Character, entry.Character);
}
else
{
@@ -178,8 +196,8 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
if (lastWrapCharIndex != INVALID_INDEX)
{
// Skip moving twice for the same character
int32 lastLineLasCharIndex = outputLines.HasItems() ? outputLines.Last().LastCharIndex : -10000;
if (lastLineLasCharIndex == lastWrapCharIndex || lastLineLasCharIndex == lastWrapCharIndex - 1 || lastLineLasCharIndex == lastWrapCharIndex - 2)
int32 lastLineLastCharIndex = outputLines.HasItems() ? outputLines.Last().LastCharIndex : -10000;
if (lastLineLastCharIndex == lastWrapCharIndex || lastLineLastCharIndex == lastWrapCharIndex - 1 || lastLineLastCharIndex == lastWrapCharIndex - 2)
{
currentIndex = nextCharIndex;
lastMoveLine = moveLine;
@@ -238,7 +256,8 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
lastMoveLine = moveLine;
}
if (textLength != 0 && (tmpLine.LastCharIndex >= tmpLine.FirstCharIndex || text[textLength - 1] == '\n'))
// Check if an additional line should be created
if (tmpLine.LastCharIndex >= tmpLine.FirstCharIndex || text[textLength - 1] == '\n')
{
// Add line
tmpLine.Size.X = cursorX;
@@ -341,7 +360,7 @@ int32 Font::HitTestText(const StringView& text, const Float2& location, const Te
// Apply kerning
if (!isWhitespace && previous.IsValid)
{
x += GetKerning(previous.Character, entry.Character);
x += entry.Font->GetKerning(previous.Character, entry.Character);
}
previous = entry;
@@ -415,7 +434,7 @@ Float2 Font::GetCharPosition(const StringView& text, int32 index, const TextLayo
// Apply kerning
if (!isWhitespace && previous.IsValid)
{
x += GetKerning(previous.Character, entry.Character);
x += entry.Font->GetKerning(previous.Character, entry.Character);
}
previous = entry;

View File

@@ -20,7 +20,7 @@ struct FontTextureAtlasSlot;
/// </summary>
API_STRUCT(NoDefault) struct TextRange
{
DECLARE_SCRIPTING_TYPE_MINIMAL(TextRange);
DECLARE_SCRIPTING_TYPE_MINIMAL(TextRange);
/// <summary>
/// The start index (inclusive).
@@ -35,7 +35,7 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(TextRange);
/// <summary>
/// Gets the range length.
/// </summary>
int32 Length() const
FORCE_INLINE int32 Length() const
{
return EndIndex - StartIndex;
}
@@ -43,7 +43,7 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(TextRange);
/// <summary>
/// Gets a value indicating whether range is empty.
/// </summary>
bool IsEmpty() const
FORCE_INLINE bool IsEmpty() const
{
return (EndIndex - StartIndex) <= 0;
}
@@ -53,7 +53,7 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(TextRange);
/// </summary>
/// <param name="index">The index.</param>
/// <returns><c>true</c> if range contains the specified character index; otherwise, <c>false</c>.</returns>
bool Contains(int32 index) const
FORCE_INLINE bool Contains(int32 index) const
{
return index >= StartIndex && index < EndIndex;
}
@@ -90,7 +90,7 @@ struct TIsPODType<TextRange>
/// </summary>
API_STRUCT(NoDefault) struct FontLineCache
{
DECLARE_SCRIPTING_TYPE_MINIMAL(FontLineCache);
DECLARE_SCRIPTING_TYPE_MINIMAL(FontLineCache);
/// <summary>
/// The root position of the line (upper left corner).
@@ -108,7 +108,7 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(FontLineCache);
API_FIELD() int32 FirstCharIndex;
/// <summary>
/// The last character index (from the input text).
/// The last character index (from the input text), inclusive.
/// </summary>
API_FIELD() int32 LastCharIndex;
};
@@ -154,7 +154,7 @@ struct TIsPODType<FontLineCache>
/// </summary>
API_STRUCT(NoDefault) struct FontCharacterEntry
{
DECLARE_SCRIPTING_TYPE_MINIMAL(FontCharacterEntry);
DECLARE_SCRIPTING_TYPE_MINIMAL(FontCharacterEntry);
/// <summary>
/// The character represented by this entry.
@@ -210,6 +210,11 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(FontCharacterEntry);
/// The slot in texture atlas, containing the pixel data of the glyph.
/// </summary>
API_FIELD() const FontTextureAtlasSlot* Slot;
/// <summary>
/// The owner font.
/// </summary>
API_FIELD() const class Font* Font;
};
template<>
@@ -223,10 +228,10 @@ struct TIsPODType<FontCharacterEntry>
/// </summary>
API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API Font : public ManagedScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Font);
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Font);
friend FontAsset;
private:
private:
FontAsset* _asset;
float _size;
int32 _height;
@@ -238,7 +243,6 @@ private:
mutable Dictionary<uint32, int32> _kerningTable;
public:
/// <summary>
/// Initializes a new instance of the <see cref="Font"/> class.
/// </summary>
@@ -252,6 +256,10 @@ public:
~Font();
public:
/// <summary>
/// The active fallback fonts.
/// </summary>
API_FIELD() static Array<AssetReference<FontAsset>, HeapAllocation> FallbackFonts;
/// <summary>
/// Gets parent font asset that contains font family used by this font.
@@ -302,13 +310,13 @@ public:
}
public:
/// <summary>
/// Gets character entry.
/// </summary>
/// <param name="c">The character.</param>
/// <param name="result">The output character entry.</param>
void GetCharacter(Char c, FontCharacterEntry& result);
/// <param name="enableFallback">True if fallback to secondary font when the primary font doesn't contains this character.</param>
void GetCharacter(Char c, FontCharacterEntry& result, bool enableFallback = true);
/// <summary>
/// Gets the kerning amount for a pair of characters.
@@ -330,7 +338,6 @@ public:
API_FUNCTION() void Invalidate();
public:
/// <summary>
/// Processes text to get cached lines for rendering.
/// </summary>
@@ -524,7 +531,6 @@ public:
void FlushFaceSize() const;
public:
// [Object]
String ToString() const override;
};

View File

@@ -199,14 +199,29 @@ bool FontAsset::Save(const StringView& path)
#endif
bool FontAsset::ContainsChar(Char c) const
{
return FT_Get_Char_Index(_face, c) > 0;
}
void FontAsset::Invalidate()
{
ScopeLock lock(Locker);
for (auto font : _fonts)
{
font->Invalidate();
}
}
uint64 FontAsset::GetMemoryUsage() const
{
Locker.Lock();
uint64 result = BinaryAsset::GetMemoryUsage();
result += sizeof(FontAsset) - sizeof(BinaryAsset);
result += sizeof(FT_FaceRec);
result += _fontFile.Length();
for (auto font : _fonts)
result += sizeof(Font);
Locker.Unlock();
return result;
}
bool FontAsset::init(AssetInitData& initData)

View File

@@ -93,6 +93,7 @@ API_CLASS(NoSpawn) class FLAXENGINE_API FontAsset : public BinaryAsset
{
DECLARE_BINARY_ASSET_HEADER(FontAsset, 3);
friend Font;
private:
FT_Face _face;
FontOptions _options;
@@ -174,11 +175,22 @@ public:
API_FUNCTION() bool Save(const StringView& path = StringView::Empty);
#endif
/// <summary>
/// Check if the font contains the glyph of a char.
/// </summary>
/// <param name="c">The char to test.</param>
/// <returns>True if the font contains the glyph of the char, otherwise false.</returns>
API_FUNCTION() bool ContainsChar(Char c) const;
/// <summary>
/// Invalidates all cached dynamic font atlases using this font. Can be used to reload font characters after changing font asset options.
/// </summary>
API_FUNCTION() void Invalidate();
public:
// [BinaryAsset]
uint64 GetMemoryUsage() const override;
protected:
// [BinaryAsset]
bool init(AssetInitData& initData) override;

View File

@@ -27,7 +27,6 @@ using namespace FontManagerImpl;
class FontManagerService : public EngineService
{
public:
FontManagerService()
: EngineService(TEXT("Font Manager"), -700)
{
@@ -155,6 +154,12 @@ bool FontManager::AddNewEntry(Font* font, Char c, FontCharacterEntry& entry)
// Get the index to the glyph in the font face
const FT_UInt glyphIndex = FT_Get_Char_Index(face, c);
#if !BUILD_RELEASE
if (glyphIndex == 0)
{
LOG(Warning, "Font `{}` doesn't contain character `\\u{:x}`, consider choosing another font. ", String(face->family_name), c);
}
#endif
// Load the glyph
const FT_Error error = FT_Load_Glyph(face, glyphIndex, glyphFlags);
@@ -284,6 +289,7 @@ bool FontManager::AddNewEntry(Font* font, Char c, FontCharacterEntry& entry)
entry.UVSize.X = static_cast<float>(slot->Width - 2 * padding);
entry.UVSize.Y = static_cast<float>(slot->Height - 2 * padding);
entry.Slot = slot;
entry.Font = font;
return false;
}

View File

@@ -27,11 +27,11 @@
#if USE_EDITOR
#define RENDER2D_CHECK_RENDERING_STATE \
if (!Render2D::IsRendering()) \
{ \
LOG(Error, "Calling Render2D is only valid during rendering."); \
return; \
}
if (!Render2D::IsRendering()) \
{ \
LOG(Error, "Calling Render2D is only valid during rendering."); \
return; \
}
#else
#define RENDER2D_CHECK_RENDERING_STATE
#endif
@@ -180,7 +180,7 @@ struct ClipMask
Rectangle Bounds;
};
Render2D::RenderingFeatures Render2D::Features = RenderingFeatures::VertexSnapping;
Render2D::RenderingFeatures Render2D::Features = RenderingFeatures::VertexSnapping | RenderingFeatures::FallbackFonts;
namespace
{
@@ -1137,8 +1137,8 @@ void DrawBatch(int32 startIndex, int32 count)
}
// Draw
Context->BindVB(ToSpan(&vb, 1)); // TODO: reduce bindings frequency
Context->BindIB(ib); // TODO: reduce bindings frequency
Context->BindVB(ToSpan(&vb, 1));
Context->BindIB(ib);
Context->DrawIndexed(countIb, 0, d.StartIB);
}
@@ -1159,6 +1159,7 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
FontCharacterEntry previous;
int32 kerning;
float scale = 1.0f / FontManager::FontScale;
const bool enableFallbackFonts = EnumHasAllFlags(Features, RenderingFeatures::FallbackFonts);
// Render all characters
FontCharacterEntry entry;
@@ -1183,7 +1184,7 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
if (currentChar != '\n')
{
// Get character entry
font->GetCharacter(currentChar, entry);
font->GetCharacter(currentChar, entry, enableFallbackFonts);
// Check if need to select/change font atlas (since characters even in the same font may be located in different atlases)
if (fontAtlas == nullptr || entry.TextureIndex != fontAtlasIndex)
@@ -1210,7 +1211,7 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
// Get kerning
if (!isWhitespace && previous.IsValid)
{
kerning = font->GetKerning(previous.Character, entry.Character);
kerning = entry.Font->GetKerning(previous.Character, entry.Character);
}
else
{
@@ -1273,6 +1274,7 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
FontCharacterEntry previous;
int32 kerning;
float scale = layout.Scale / FontManager::FontScale;
const bool enableFallbackFonts = EnumHasAllFlags(Features, RenderingFeatures::FallbackFonts);
// Process text to get lines
Lines.Clear();
@@ -1299,10 +1301,14 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
// Render all characters from the line
for (int32 charIndex = line.FirstCharIndex; charIndex <= line.LastCharIndex; charIndex++)
{
const Char c = text[charIndex];
if (c != '\n')
// Cache current character
const Char currentChar = text[charIndex];
// Check if it isn't a newline character
if (currentChar != '\n')
{
font->GetCharacter(c, entry);
// Get character entry
font->GetCharacter(currentChar, entry, enableFallbackFonts);
// Check if need to select/change font atlas (since characters even in the same font may be located in different atlases)
if (fontAtlas == nullptr || entry.TextureIndex != fontAtlasIndex)
@@ -1324,10 +1330,10 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
}
// Get kerning
const bool isWhitespace = StringUtils::IsWhitespace(c);
const bool isWhitespace = StringUtils::IsWhitespace(currentChar);
if (!isWhitespace && previous.IsValid)
{
kerning = font->GetKerning(previous.Character, entry.Character);
kerning = entry.Font->GetKerning(previous.Character, entry.Character);
}
else
{
@@ -1931,7 +1937,7 @@ void Render2D::DrawBlur(const Rectangle& rect, float blurStrength)
void Render2D::DrawTexturedTriangles(GPUTexture* t, const Span<Float2>& vertices, const Span<Float2>& uvs)
{
RENDER2D_CHECK_RENDERING_STATE;
CHECK(vertices.Length() == uvs.Length())
CHECK(vertices.Length() == uvs.Length());
Render2DDrawCall& drawCall = DrawCalls.AddOne();
drawCall.Type = DrawCallType::FillTexture;
@@ -1977,7 +1983,7 @@ void Render2D::DrawTexturedTriangles(GPUTexture* t, const Span<uint16>& indices,
drawCall.StartIB = IBIndex;
drawCall.CountIB = indices.Length();
drawCall.AsTexture.Ptr = t;
for (int32 i = 0; i < indices.Length();)
{
const uint16 i0 = indices.Get()[i++];

View File

@@ -44,6 +44,11 @@ API_CLASS(Static) class FLAXENGINE_API Render2D
/// Enables automatic geometry vertices snapping to integer coordinates in screen space. Reduces aliasing and sampling artifacts. Might be disabled for 3D projection viewport or for complex UI transformations.
/// </summary>
VertexSnapping = 1,
/// <summary>
/// Enables automatic characters usage from fallback fonts.
/// </summary>
FallbackFonts = 2,
};
struct CustomData
@@ -452,3 +457,5 @@ public:
/// <param name="color">The color.</param>
API_FUNCTION() static void FillTriangle(const Float2& p0, const Float2& p1, const Float2& p2, const Color& color);
};
DECLARE_ENUM_OPERATORS(Render2D::RenderingFeatures);

View File

@@ -280,7 +280,7 @@ namespace FlaxEngine.GUI
foreach (var id in ids)
{
var path = Content.GetEditorAssetPath(id);
if (!string.IsNullOrEmpty(path) &&
if (!string.IsNullOrEmpty(path) &&
string.Equals(name, System.IO.Path.GetFileNameWithoutExtension(path), System.StringComparison.OrdinalIgnoreCase))
{
return Content.LoadAsync(id, type);

View File

@@ -280,13 +280,13 @@ namespace FlaxEngine.GUI
/// </summary>
[EditorDisplay("Border Style"), EditorOrder(2010), Tooltip("Whether to have a border."), ExpandGroups]
public bool HasBorder { get; set; } = true;
/// <summary>
/// Gets or sets the border thickness.
/// </summary>
[EditorDisplay("Border Style"), EditorOrder(2011), Tooltip("The thickness of the border."), Limit(0)]
public float BorderThickness { get; set; } = 1.0f;
/// <summary>
/// Gets or sets the color of the border (Transparent if not used).
/// </summary>

View File

@@ -239,7 +239,7 @@ void TextRender::UpdateLayout()
const bool isWhitespace = StringUtils::IsWhitespace(c);
if (!isWhitespace && previous.IsValid)
{
kerning = font->GetKerning(previous.Character, entry.Character);
kerning = entry.Font->GetKerning(previous.Character, entry.Character);
}
else
{