Add more tags to Rich Text Box
This commit is contained in:
@@ -141,7 +141,7 @@ namespace FlaxEditor.Scripting
|
||||
Utilities.Utils.InitDefaultValues(value);
|
||||
return value;
|
||||
}
|
||||
throw new NotSupportedException("Cannot create default value for type " + type);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -274,7 +274,7 @@ public:
|
||||
/// <summary>
|
||||
/// Gets the largest vertical distance above the baseline for any character in the font.
|
||||
/// </summary>
|
||||
FORCE_INLINE int32 GetAscender() const
|
||||
API_PROPERTY() FORCE_INLINE int32 GetAscender() const
|
||||
{
|
||||
return _ascender;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Font.h"
|
||||
#include "FontManager.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||
#include "Engine/Content/Upgraders/FontAssetUpgrader.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
@@ -13,7 +14,7 @@
|
||||
#include "Engine/Platform/FileSystem.h"
|
||||
#endif
|
||||
|
||||
REGISTER_BINARY_ASSET_WITH_UPGRADER(FontAsset, "FlaxEngine.FontAsset", FontAssetUpgrader, false);
|
||||
REGISTER_BINARY_ASSET_WITH_UPGRADER(FontAsset, "FlaxEngine.FontAsset", FontAssetUpgrader, true);
|
||||
|
||||
FontAsset::FontAsset(const SpawnParams& params, const AssetInfo* info)
|
||||
: BinaryAsset(params, info)
|
||||
@@ -40,15 +41,7 @@ Asset::LoadResult FontAsset::load()
|
||||
_fontFile.Swap(chunk0->Data);
|
||||
|
||||
// Create font face
|
||||
const FT_Error error = FT_New_Memory_Face(FontManager::GetLibrary(), _fontFile.Get(), static_cast<FT_Long>(_fontFile.Length()), 0, &_face);
|
||||
if (error)
|
||||
{
|
||||
_face = nullptr;
|
||||
LOG_FT_ERROR(error);
|
||||
return LoadResult::Failed;
|
||||
}
|
||||
|
||||
return LoadResult::Ok;
|
||||
return Init() ? LoadResult::Failed : LoadResult::Ok;
|
||||
}
|
||||
|
||||
void FontAsset::unload(bool isReloading)
|
||||
@@ -81,6 +74,22 @@ AssetChunksFlag FontAsset::getChunksToPreload() const
|
||||
return GET_CHUNK_FLAG(0);
|
||||
}
|
||||
|
||||
bool FontAsset::Init()
|
||||
{
|
||||
const FT_Error error = FT_New_Memory_Face(FontManager::GetLibrary(), _fontFile.Get(), static_cast<FT_Long>(_fontFile.Length()), 0, &_face);
|
||||
if (error)
|
||||
{
|
||||
_face = nullptr;
|
||||
LOG_FT_ERROR(error);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
void FontAsset::SetOptions(const FontOptions& value)
|
||||
{
|
||||
_options = value;
|
||||
}
|
||||
|
||||
Font* FontAsset::CreateFont(int32 size)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
@@ -89,6 +98,8 @@ Font* FontAsset::CreateFont(int32 size)
|
||||
return nullptr;
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
if (_face == nullptr)
|
||||
return nullptr;
|
||||
|
||||
// Check if font with that size has already been created
|
||||
for (auto font : _fonts)
|
||||
@@ -100,6 +111,46 @@ Font* FontAsset::CreateFont(int32 size)
|
||||
return New<Font>(this, size);
|
||||
}
|
||||
|
||||
FontAsset* FontAsset::GetBold()
|
||||
{
|
||||
ScopeLock lock(Locker);
|
||||
if (_options.Flags & FontFlags::Bold)
|
||||
return this;
|
||||
if (!_virtualBold)
|
||||
{
|
||||
_virtualBold = Content::CreateVirtualAsset<FontAsset>();
|
||||
_virtualBold->Init(_fontFile);
|
||||
auto options = _options;
|
||||
options.Flags |= FontFlags::Bold;
|
||||
_virtualBold->SetOptions(options);
|
||||
}
|
||||
return _virtualBold;
|
||||
}
|
||||
|
||||
FontAsset* FontAsset::GetItalic()
|
||||
{
|
||||
ScopeLock lock(Locker);
|
||||
if (_options.Flags & FontFlags::Italic)
|
||||
return this;
|
||||
if (!_virtualItalic)
|
||||
{
|
||||
_virtualItalic = Content::CreateVirtualAsset<FontAsset>();
|
||||
_virtualItalic->Init(_fontFile);
|
||||
auto options = _options;
|
||||
options.Flags |= FontFlags::Italic;
|
||||
_virtualItalic->SetOptions(options);
|
||||
}
|
||||
return _virtualItalic;
|
||||
}
|
||||
|
||||
bool FontAsset::Init(const BytesContainer& fontFile)
|
||||
{
|
||||
ScopeLock lock(Locker);
|
||||
unload(true);
|
||||
_fontFile.Copy(fontFile);
|
||||
return Init();
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool FontAsset::Save(const StringView& path)
|
||||
@@ -148,6 +199,9 @@ void FontAsset::Invalidate()
|
||||
|
||||
bool FontAsset::init(AssetInitData& initData)
|
||||
{
|
||||
if (IsVirtual())
|
||||
return false;
|
||||
|
||||
// Validate
|
||||
if (initData.SerializedVersion != SerializedVersion)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Content/BinaryAsset.h"
|
||||
#include "Engine/Content/AssetReference.h"
|
||||
|
||||
class Font;
|
||||
class FontManager;
|
||||
@@ -72,7 +73,7 @@ DECLARE_ENUM_OPERATORS(FontFlags);
|
||||
/// </summary>
|
||||
API_STRUCT() struct FontOptions
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(FontOptions);
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(FontOptions);
|
||||
|
||||
/// <summary>
|
||||
/// The hinting.
|
||||
@@ -90,17 +91,17 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(FontOptions);
|
||||
/// </summary>
|
||||
API_CLASS(NoSpawn) class FLAXENGINE_API FontAsset : public BinaryAsset
|
||||
{
|
||||
DECLARE_BINARY_ASSET_HEADER(FontAsset, 3);
|
||||
DECLARE_BINARY_ASSET_HEADER(FontAsset, 3);
|
||||
friend Font;
|
||||
private:
|
||||
|
||||
FT_Face _face;
|
||||
FontOptions _options;
|
||||
BytesContainer _fontFile;
|
||||
Array<Font*, InlinedAllocation<32>> _fonts;
|
||||
AssetReference<FontAsset> _virtualBold;
|
||||
AssetReference<FontAsset> _virtualItalic;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets the font family name.
|
||||
/// </summary>
|
||||
@@ -130,13 +131,9 @@ public:
|
||||
/// <summary>
|
||||
/// Sets the font options.
|
||||
/// </summary>
|
||||
API_PROPERTY() void SetOptions(const FontOptions& value)
|
||||
{
|
||||
_options = value;
|
||||
}
|
||||
API_PROPERTY() void SetOptions(const FontOptions& value);
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Creates the font object of given characters size.
|
||||
/// </summary>
|
||||
@@ -144,15 +141,32 @@ public:
|
||||
/// <returns>The created font object.</returns>
|
||||
API_FUNCTION() Font* CreateFont(int32 size);
|
||||
|
||||
#if USE_EDITOR
|
||||
/// <summary>
|
||||
/// Gets the font with bold style. Returns itself or creates a new virtual font asset using this font but with bold option enabled.
|
||||
/// </summary>
|
||||
/// <returns>The virtual font or this.</returns>
|
||||
API_FUNCTION() FontAsset* GetBold();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the font with italic style. Returns itself or creates a new virtual font asset using this font but with italic option enabled.
|
||||
/// </summary>
|
||||
/// <returns>The virtual font or this.</returns>
|
||||
API_FUNCTION() FontAsset* GetItalic();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the font with a custom font file data.
|
||||
/// </summary>
|
||||
/// <param name="fontFile">Raw bytes with font file data.</param>
|
||||
/// <returns>True if cannot init, otherwise false.</returns>
|
||||
API_FUNCTION() bool Init(const BytesContainer& fontFile);
|
||||
|
||||
#if USE_EDITOR
|
||||
/// <summary>
|
||||
/// Saves this asset to the file. Supported only in Editor.
|
||||
/// </summary>
|
||||
/// <param name="path">The custom asset path to use for the saving. Use empty value to save this asset to its own storage location. Can be used to duplicate asset. Must be specified when saving virtual asset.</param>
|
||||
/// <returns>True if cannot save data, otherwise false.</returns>
|
||||
API_FUNCTION() bool Save(const StringView& path = StringView::Empty);
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
@@ -161,10 +175,12 @@ public:
|
||||
API_FUNCTION() void Invalidate();
|
||||
|
||||
protected:
|
||||
|
||||
// [BinaryAsset]
|
||||
bool init(AssetInitData& initData) override;
|
||||
LoadResult load() override;
|
||||
void unload(bool isReloading) override;
|
||||
AssetChunksFlag getChunksToPreload() const override;
|
||||
|
||||
private:
|
||||
bool Init();
|
||||
};
|
||||
|
||||
@@ -106,6 +106,24 @@ namespace FlaxEngine
|
||||
return _cachedFont;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bold font object described by the structure.
|
||||
/// </summary>
|
||||
/// <returns>The bold font asset.</returns>
|
||||
public FontReference GetBold()
|
||||
{
|
||||
return new FontReference(_font?.GetBold(), _size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the italic font object described by the structure.
|
||||
/// </summary>
|
||||
/// <returns>The bold font asset.</returns>
|
||||
public FontReference GetItalic()
|
||||
{
|
||||
return new FontReference(_font?.GetItalic(), _size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="FontReference" /> is equal to this instance.
|
||||
/// </summary>
|
||||
|
||||
@@ -12,6 +12,11 @@ namespace FlaxEngine.GUI
|
||||
/// </summary>
|
||||
public struct ParsingContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Text box control.
|
||||
/// </summary>
|
||||
public RichTextBox Control;
|
||||
|
||||
/// <summary>
|
||||
/// HTML tags parser.
|
||||
/// </summary>
|
||||
@@ -55,6 +60,10 @@ namespace FlaxEngine.GUI
|
||||
{
|
||||
{ "br", ProcessBr },
|
||||
{ "color", ProcessColor },
|
||||
{ "alpha", ProcessAlpha },
|
||||
{ "style", ProcessStyle },
|
||||
{ "b", ProcessBold },
|
||||
{ "i", ProcessItalic },
|
||||
};
|
||||
|
||||
private HtmlParser _parser = new HtmlParser();
|
||||
@@ -75,6 +84,7 @@ namespace FlaxEngine.GUI
|
||||
_styleStack.Push(_textStyle);
|
||||
var context = new ParsingContext
|
||||
{
|
||||
Control = this,
|
||||
Parser = _parser,
|
||||
StyleStack = _styleStack,
|
||||
};
|
||||
|
||||
@@ -34,5 +34,79 @@ namespace FlaxEngine.GUI
|
||||
context.StyleStack.Push(style);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessAlpha(ref ParsingContext context, ref HtmlTag tag)
|
||||
{
|
||||
if (tag.IsSlash)
|
||||
{
|
||||
context.StyleStack.Pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
var style = context.StyleStack.Peek();
|
||||
if (tag.Attributes.TryGetValue(string.Empty, out var alphaText))
|
||||
{
|
||||
if (alphaText.Length == 3 && alphaText[0] == '#')
|
||||
{
|
||||
style.Color.A = ((StringUtils.HexDigit(alphaText[1]) << 4) + StringUtils.HexDigit(alphaText[2])) / 255.0f;
|
||||
}
|
||||
else if (alphaText.Length > 1 && alphaText[alphaText.Length - 1] == '%')
|
||||
{
|
||||
style.Color.A = float.Parse(alphaText.Substring(0, alphaText.Length - 1)) / 100.0f;
|
||||
}
|
||||
}
|
||||
context.StyleStack.Push(style);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessStyle(ref ParsingContext context, ref HtmlTag tag)
|
||||
{
|
||||
if (tag.IsSlash)
|
||||
{
|
||||
context.StyleStack.Pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
var style = context.StyleStack.Peek();
|
||||
if (tag.Attributes.TryGetValue(string.Empty, out var styleName))
|
||||
{
|
||||
if (context.Control.Styles.TryGetValue(styleName, out var customStyle))
|
||||
{
|
||||
if (customStyle.Font == null)
|
||||
customStyle.Font = style.Font;
|
||||
style = customStyle;
|
||||
}
|
||||
}
|
||||
context.StyleStack.Push(style);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessBold(ref ParsingContext context, ref HtmlTag tag)
|
||||
{
|
||||
if (tag.IsSlash)
|
||||
{
|
||||
context.StyleStack.Pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
var style = context.StyleStack.Peek();
|
||||
style.Font = style.Font.GetBold();
|
||||
context.StyleStack.Push(style);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessItalic(ref ParsingContext context, ref HtmlTag tag)
|
||||
{
|
||||
if (tag.IsSlash)
|
||||
{
|
||||
context.StyleStack.Pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
var style = context.StyleStack.Peek();
|
||||
style.Font = style.Font.GetItalic();
|
||||
context.StyleStack.Push(style);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FlaxEngine.GUI
|
||||
{
|
||||
/// <summary>
|
||||
@@ -23,6 +25,12 @@ namespace FlaxEngine.GUI
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The collection of custom text styles to apply (named).
|
||||
/// </summary>
|
||||
[EditorOrder(30)]
|
||||
public Dictionary<string, TextBlockStyle> Styles = new Dictionary<string, TextBlockStyle>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RichTextBox"/> class.
|
||||
/// </summary>
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// Updates the text blocks.
|
||||
/// </summary>
|
||||
protected virtual void UpdateTextBlocks()
|
||||
public virtual void UpdateTextBlocks()
|
||||
{
|
||||
Profiler.BeginEvent("RichTextBoxBase.UpdateTextBlocks");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user