Merge branch 'HydrogenC-master'
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -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
|
||||
|
||||
BIN
Content/Editor/Fonts/NotoSansSC-Regular.flax
LFS
Normal file
BIN
Content/Editor/Fonts/NotoSansSC-Regular.flax
LFS
Normal file
Binary file not shown.
@@ -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>
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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++];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user