Add font fallback
Note: All the `First()` in the code are temperary workarounds to make it work and require refractoring
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.GUI;
|
||||
using FlaxEditor.GUI.Drag;
|
||||
using FlaxEditor.GUI.Tree;
|
||||
@@ -140,8 +141,8 @@ namespace FlaxEditor.Content
|
||||
var textRect = TextRect;
|
||||
for (int i = 0; i < ranges.Length; i++)
|
||||
{
|
||||
var start = font.GetCharPosition(text, ranges[i].StartIndex);
|
||||
var end = font.GetCharPosition(text, ranges[i].EndIndex);
|
||||
var start = font.First().GetCharPosition(text, ranges[i].StartIndex);
|
||||
var end = font.First().GetCharPosition(text, ranges[i].EndIndex);
|
||||
_highlights.Add(new Rectangle(start.X + textRect.X, textRect.Y, end.X - start.X, textRect.Height));
|
||||
}
|
||||
isThisVisible = true;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.Actions;
|
||||
using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI;
|
||||
@@ -42,7 +43,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
|
||||
// Add script button
|
||||
var buttonText = "Add script";
|
||||
var textSize = Style.Current.FontMedium.MeasureText(buttonText);
|
||||
var textSize = Style.Current.FontMedium.First().MeasureText(buttonText);
|
||||
float addScriptButtonWidth = (textSize.X < 60.0f) ? 60.0f : textSize.X + 4;
|
||||
var buttonHeight = (textSize.Y < 18) ? 18 : textSize.Y + 4;
|
||||
_addScriptsButton = new Button
|
||||
|
||||
@@ -247,7 +247,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
// Info
|
||||
var info = new Label(0, title.Bottom, DialogWidth, InfoHeight)
|
||||
{
|
||||
Font = new FontReference(style.FontSmall),
|
||||
Font = new FontReference(style.FontSmall.First()),
|
||||
Text = "Shift: also set bounds\nControl: also set pivot",
|
||||
Parent = this
|
||||
};
|
||||
@@ -423,7 +423,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
// Set control type button
|
||||
var space = layout.Space(20);
|
||||
var buttonText = "Set Type";
|
||||
var textSize = FlaxEngine.GUI.Style.Current.FontMedium.MeasureText(buttonText);
|
||||
var textSize = FlaxEngine.GUI.Style.Current.FontMedium.First().MeasureText(buttonText);
|
||||
float setTypeButtonWidth = (textSize.X < 60.0f) ? 60.0f : textSize.X + 4;
|
||||
var setTypeButton = new Button
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
@@ -100,7 +101,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
_linkButton.Clicked += ToggleLink;
|
||||
ToggleEnabled();
|
||||
SetLinkStyle();
|
||||
var textSize = FlaxEngine.GUI.Style.Current.FontMedium.MeasureText(LinkedLabel.Text.Value);
|
||||
var textSize = FlaxEngine.GUI.Style.Current.FontMedium.First().MeasureText(LinkedLabel.Text.Value);
|
||||
_linkButton.LocalX += textSize.X + 10;
|
||||
LinkedLabel.SetupContextMenu += (label, menu, editor) =>
|
||||
{
|
||||
|
||||
@@ -631,7 +631,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
TooltipText = "Edit...",
|
||||
Parent = _label,
|
||||
};
|
||||
var textSize = FlaxEngine.GUI.Style.Current.FontMedium.MeasureText(buttonText);
|
||||
var textSize = FlaxEngine.GUI.Style.Current.FontMedium.First().MeasureText(buttonText);
|
||||
if (textSize.Y > button.Width)
|
||||
button.Width = textSize.Y + 2;
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ namespace FlaxEditor
|
||||
/// </summary>
|
||||
public static string PrimaryFont = "Editor/Fonts/Roboto-Regular";
|
||||
|
||||
public static string CJKFont = "Editor/Fonts/NotoSansSC-Medium";
|
||||
|
||||
/// <summary>
|
||||
/// The Inconsolata Regular font.
|
||||
/// </summary>
|
||||
|
||||
@@ -273,7 +273,7 @@ namespace FlaxEditor.GUI
|
||||
MaximumItemsInViewCount = 20;
|
||||
|
||||
var style = Style.Current;
|
||||
Font = new FontReference(style.FontMedium);
|
||||
Font = new FontReference(style.FontMedium.First());
|
||||
TextColor = style.Foreground;
|
||||
BackgroundColor = style.BackgroundNormal;
|
||||
BackgroundColorHighlighted = BackgroundColor;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
@@ -233,11 +234,11 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
{
|
||||
var style = Style.Current;
|
||||
float width = 20;
|
||||
if (style.FontMedium)
|
||||
if (style.FontMedium.First())
|
||||
{
|
||||
width += style.FontMedium.MeasureText(Text).X;
|
||||
width += style.FontMedium.First().MeasureText(Text).X;
|
||||
if (!string.IsNullOrEmpty(ShortKeys))
|
||||
width += 40 + style.FontMedium.MeasureText(ShortKeys).X;
|
||||
width += 40 + style.FontMedium.First().MeasureText(ShortKeys).X;
|
||||
}
|
||||
|
||||
return Mathf.Max(width, base.MinimumWidth);
|
||||
|
||||
@@ -437,7 +437,7 @@ namespace FlaxEditor.GUI
|
||||
_contentsColor = style.Background.RGBMultiplied(0.7f);
|
||||
_linesColor = style.ForegroundDisabled.RGBMultiplied(0.7f);
|
||||
_labelsColor = style.ForegroundDisabled;
|
||||
_labelsFont = style.FontSmall;
|
||||
_labelsFont = style.FontSmall.First();
|
||||
|
||||
_mainPanel = new Panel(ScrollBars.Both)
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ using FlaxEngine;
|
||||
using FlaxEngine.Assertions;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEditor.Options;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEditor.GUI.Docking
|
||||
{
|
||||
@@ -488,7 +489,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
{
|
||||
var style = Style.Current;
|
||||
if (style?.FontMedium != null)
|
||||
_titleSize = style.FontMedium.MeasureText(_title);
|
||||
_titleSize = style.FontMedium.First().MeasureText(_title);
|
||||
}
|
||||
|
||||
base.PerformLayoutBeforeChildren();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.GUI.Input;
|
||||
using FlaxEditor.Utilities;
|
||||
@@ -86,8 +87,8 @@ namespace FlaxEditor.GUI
|
||||
var font = style.FontSmall;
|
||||
for (int i = 0; i < ranges.Length; i++)
|
||||
{
|
||||
var start = font.GetCharPosition(Name, ranges[i].StartIndex);
|
||||
var end = font.GetCharPosition(Name, ranges[i].EndIndex);
|
||||
var start = font.First().GetCharPosition(Name, ranges[i].StartIndex);
|
||||
var end = font.First().GetCharPosition(Name, ranges[i].EndIndex);
|
||||
_highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
|
||||
}
|
||||
Visible = true;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEditor.GUI
|
||||
{
|
||||
@@ -101,8 +102,8 @@ namespace FlaxEditor.GUI
|
||||
var style = Style.Current;
|
||||
float width = 18;
|
||||
|
||||
if (style.FontMedium)
|
||||
width += style.FontMedium.MeasureText(Text).X;
|
||||
if (style.FontMedium.First())
|
||||
width += style.FontMedium.First().MeasureText(Text).X;
|
||||
|
||||
Width = width;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEditor.GUI
|
||||
{
|
||||
@@ -65,9 +66,9 @@ namespace FlaxEditor.GUI
|
||||
{
|
||||
var style = Style.Current;
|
||||
|
||||
if (style.FontMedium)
|
||||
if (style.FontMedium.First())
|
||||
{
|
||||
Width = style.FontMedium.MeasureText(Text).X + 2 * DefaultMargin;
|
||||
Width = style.FontMedium.First().MeasureText(Text).X + 2 * DefaultMargin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
@@ -38,8 +39,8 @@ namespace FlaxEditor.GUI
|
||||
{
|
||||
Depth = -1;
|
||||
|
||||
if (Height < Style.Current.FontMedium.Height)
|
||||
Height = Style.Current.FontMedium.Height + 4;
|
||||
if (Height < Style.Current.FontMedium.First().Height)
|
||||
Height = Style.Current.FontMedium.First().Height + 4;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
@@ -129,7 +130,7 @@ namespace FlaxEditor.GUI
|
||||
Render2D.FillRectangle(rect, column.TitleBackgroundColor);
|
||||
|
||||
var style = Style.Current;
|
||||
var font = column.TitleFont ?? style.FontMedium;
|
||||
var font = column.TitleFont ?? style.FontMedium.First();
|
||||
Render2D.DrawText(font, column.Title, rect, column.TitleColor, TextAlignment.Center, TextAlignment.Center);
|
||||
|
||||
if (columnIndex < _columns.Length - 1)
|
||||
|
||||
@@ -345,7 +345,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
if (_previewValue != null)
|
||||
{
|
||||
// Based on Track.Draw for track text placement
|
||||
var left = _xOffset + 16 + Style.Current.FontSmall.MeasureText(Title ?? Name).X;
|
||||
var left = _xOffset + 16 + Style.Current.FontSmall.First().MeasureText(Title ?? Name).X;
|
||||
if (Icon.IsValid)
|
||||
left += 18;
|
||||
if (IsExpanded)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
@@ -150,8 +151,8 @@ namespace FlaxEditor.GUI
|
||||
|
||||
if (hasSprite)
|
||||
width += iconSize;
|
||||
if (!string.IsNullOrEmpty(_text) && style.FontMedium)
|
||||
width += style.FontMedium.MeasureText(_text).X + (hasSprite ? DefaultMargin : 0);
|
||||
if (!string.IsNullOrEmpty(_text) && style.FontMedium.First())
|
||||
width += style.FontMedium.First().MeasureText(_text).X + (hasSprite ? DefaultMargin : 0);
|
||||
|
||||
Width = width;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
@@ -317,7 +318,7 @@ namespace FlaxEditor.GUI.Tree
|
||||
BackgroundColorSelected = style.BackgroundSelected;
|
||||
BackgroundColorHighlighted = style.BackgroundHighlighted;
|
||||
BackgroundColorSelectedUnfocused = style.LightBackground;
|
||||
TextFont = new FontReference(style.FontSmall);
|
||||
TextFont = new FontReference(style.FontSmall.First());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -237,12 +237,18 @@ namespace FlaxEditor.Options
|
||||
public int NumberOfGameClientsToLaunch = 1;
|
||||
|
||||
private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.PrimaryFont);
|
||||
private static FontAsset _cjkFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.CJKFont);
|
||||
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);
|
||||
|
||||
public FontReference CJKFont
|
||||
{
|
||||
get => new FontReference(_cjkFont, 9);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title font for editor UI.
|
||||
/// </summary>
|
||||
|
||||
@@ -261,8 +261,9 @@ namespace FlaxEditor.Options
|
||||
// Fonts
|
||||
FontTitle = options.Interface.TitleFont.GetFont(),
|
||||
FontLarge = options.Interface.LargeFont.GetFont(),
|
||||
FontMedium = options.Interface.MediumFont.GetFont(),
|
||||
FontSmall = options.Interface.SmallFont.GetFont(),
|
||||
FontMedium = new Font[] { options.Interface.MediumFont.GetFont(), options.Interface.CJKFont.GetFont() },
|
||||
FontSmall = new Font[] { options.Interface.SmallFont.GetFont(), options.Interface.CJKFont.GetFont() },
|
||||
FontCJK = options.Interface.CJKFont.GetFont(),
|
||||
|
||||
// Icons
|
||||
ArrowDown = Editor.Icons.ArrowDown12,
|
||||
@@ -314,8 +315,8 @@ namespace FlaxEditor.Options
|
||||
// Fonts
|
||||
FontTitle = options.Interface.TitleFont.GetFont(),
|
||||
FontLarge = options.Interface.LargeFont.GetFont(),
|
||||
FontMedium = options.Interface.MediumFont.GetFont(),
|
||||
FontSmall = options.Interface.SmallFont.GetFont(),
|
||||
FontMedium = new Font[] { options.Interface.MediumFont.GetFont(), options.Interface.CJKFont.GetFont() },
|
||||
FontSmall = new Font[] { options.Interface.SmallFont.GetFont(), options.Interface.CJKFont.GetFont() },
|
||||
|
||||
// Icons
|
||||
ArrowDown = Editor.Icons.ArrowDown12,
|
||||
|
||||
@@ -142,8 +142,8 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
var textRect = TextRect;
|
||||
for (int i = 0; i < ranges.Length; i++)
|
||||
{
|
||||
var start = font.GetCharPosition(text, ranges[i].StartIndex);
|
||||
var end = font.GetCharPosition(text, ranges[i].EndIndex);
|
||||
var start = font.First().GetCharPosition(text, ranges[i].StartIndex);
|
||||
var end = font.First().GetCharPosition(text, ranges[i].EndIndex);
|
||||
_highlights.Add(new Rectangle(start.X + textRect.X, textRect.Y, end.X - start.X, textRect.Height));
|
||||
}
|
||||
isThisVisible = true;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.CustomEditors.Dedicated;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.GUI.Drag;
|
||||
@@ -100,7 +101,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
_debugRelevant = Behavior.GetNodeDebugRelevancy(instance, behavior);
|
||||
_debugInfo = Behavior.GetNodeDebugInfo(instance, behavior);
|
||||
if (!string.IsNullOrEmpty(_debugInfo))
|
||||
_debugInfoSize = Style.Current.FontSmall.MeasureText(_debugInfo);
|
||||
_debugInfoSize = Style.Current.FontSmall.First().MeasureText(_debugInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -200,8 +200,8 @@ namespace FlaxEditor.Surface.ContextMenu
|
||||
var font = style.FontSmall;
|
||||
for (int i = 0; i < ranges.Length; i++)
|
||||
{
|
||||
var start = font.GetCharPosition(_archetype.Title, ranges[i].StartIndex);
|
||||
var end = font.GetCharPosition(_archetype.Title, ranges[i].EndIndex);
|
||||
var start = font.First().GetCharPosition(_archetype.Title, ranges[i].StartIndex);
|
||||
var end = font.First().GetCharPosition(_archetype.Title, ranges[i].EndIndex);
|
||||
_highlights.Add(new Rectangle(start.X + textRect.X, 0, end.X - start.X, Height));
|
||||
|
||||
if (ranges[i].StartIndex <= 0)
|
||||
@@ -222,8 +222,8 @@ namespace FlaxEditor.Surface.ContextMenu
|
||||
_highlights.Clear();
|
||||
var style = Style.Current;
|
||||
var font = style.FontSmall;
|
||||
var start = font.GetCharPosition(_archetype.Title, 0);
|
||||
var end = font.GetCharPosition(_archetype.Title, _archetype.Title.Length - 1);
|
||||
var start = font.First().GetCharPosition(_archetype.Title, 0);
|
||||
var end = font.First().GetCharPosition(_archetype.Title, _archetype.Title.Length - 1);
|
||||
_highlights.Add(new Rectangle(start.X + textRect.X, 0, end.X - start.X, Height));
|
||||
_isFullMatch = true;
|
||||
Visible = true;
|
||||
@@ -237,8 +237,8 @@ namespace FlaxEditor.Surface.ContextMenu
|
||||
_highlights.Clear();
|
||||
var style = Style.Current;
|
||||
var font = style.FontSmall;
|
||||
var start = font.GetCharPosition(_archetype.Title, 0);
|
||||
var end = font.GetCharPosition(_archetype.Title, _archetype.Title.Length - 1);
|
||||
var start = font.First().GetCharPosition(_archetype.Title, 0);
|
||||
var end = font.First().GetCharPosition(_archetype.Title, _archetype.Title.Length - 1);
|
||||
_highlights.Add(new Rectangle(start.X + textRect.X, 0, end.X - start.X, Height));
|
||||
Visible = true;
|
||||
|
||||
@@ -286,7 +286,7 @@ namespace FlaxEditor.Surface.ContextMenu
|
||||
Render2D.DrawText(style.FontSmall, _archetype.Title, textRect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center);
|
||||
if (_archetype.SubTitle != null)
|
||||
{
|
||||
var titleLength = style.FontSmall.MeasureText(_archetype.Title).X;
|
||||
var titleLength = style.FontSmall.First().MeasureText(_archetype.Title).X;
|
||||
var subTitleRect = new Rectangle(textRect.X + titleLength, textRect.Y, textRect.Width - titleLength, textRect.Height);
|
||||
Render2D.DrawText(style.FontSmall, _archetype.SubTitle, subTitleRect, style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center);
|
||||
}
|
||||
|
||||
@@ -1428,7 +1428,7 @@ namespace FlaxEditor.Surface.Elements
|
||||
|
||||
if (_defaultValueEditor != null)
|
||||
{
|
||||
_defaultValueEditor.Location = new Float2(X + Width + 8 + Style.Current.FontSmall.MeasureText(Text).X, Y);
|
||||
_defaultValueEditor.Location = new Float2(X + Width + 8 + Style.Current.FontSmall.First().MeasureText(Text).X, Y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1635,7 +1635,7 @@ namespace FlaxEditor.Surface.Elements
|
||||
{
|
||||
if (DefaultValueEditors[i].CanUse(this, ref _currentType))
|
||||
{
|
||||
var bounds = new Rectangle(X + Width + 8 + Style.Current.FontSmall.MeasureText(Text).X, Y, 90, Height);
|
||||
var bounds = new Rectangle(X + Width + 8 + Style.Current.FontSmall.First().MeasureText(Text).X, Y, 90, Height);
|
||||
_editor = DefaultValueEditors[i];
|
||||
try
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Surface.Elements;
|
||||
using FlaxEditor.Surface.Undo;
|
||||
@@ -199,7 +200,7 @@ namespace FlaxEditor.Surface
|
||||
continue;
|
||||
if (child is InputBox inputBox)
|
||||
{
|
||||
var boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 20;
|
||||
var boxWidth = boxLabelFont.First().MeasureText(inputBox.Text).X + 20;
|
||||
if (inputBox.DefaultValueEditor != null)
|
||||
boxWidth += inputBox.DefaultValueEditor.Width + 4;
|
||||
leftWidth = Mathf.Max(leftWidth, boxWidth);
|
||||
@@ -207,7 +208,7 @@ namespace FlaxEditor.Surface
|
||||
}
|
||||
else if (child is OutputBox outputBox)
|
||||
{
|
||||
rightWidth = Mathf.Max(rightWidth, boxLabelFont.MeasureText(outputBox.Text).X + 20);
|
||||
rightWidth = Mathf.Max(rightWidth, boxLabelFont.First().MeasureText(outputBox.Text).X + 20);
|
||||
rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f);
|
||||
}
|
||||
else if (child is Control control)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.GUI.Tabs;
|
||||
using FlaxEditor.Modules;
|
||||
using FlaxEditor.SceneGraph.Actors;
|
||||
@@ -147,7 +148,7 @@ namespace FlaxEditor.Tools.Foliage
|
||||
Parent = _noFoliagePanel,
|
||||
Enabled = false
|
||||
};
|
||||
var textSize = Style.Current.FontMedium.MeasureText(buttonText);
|
||||
var textSize = Style.Current.FontMedium.First().MeasureText(buttonText);
|
||||
if (_createNewFoliage.Width < textSize.X)
|
||||
{
|
||||
_createNewFoliage.LocalX -= (textSize.X - _createNewFoliage.Width) / 2;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FlaxEditor.GUI.Tabs;
|
||||
using FlaxEditor.Modules;
|
||||
using FlaxEditor.SceneGraph.Actors;
|
||||
@@ -105,7 +106,7 @@ namespace FlaxEditor.Tools.Terrain
|
||||
Parent = _noTerrainPanel,
|
||||
Enabled = false
|
||||
};
|
||||
var textSize = Style.Current.FontMedium.MeasureText(buttonText);
|
||||
var textSize = Style.Current.FontMedium.First().MeasureText(buttonText);
|
||||
if (_createTerrainButton.Width < textSize.X)
|
||||
{
|
||||
_createTerrainButton.LocalX -= (textSize.X - _createTerrainButton.Width) / 2;
|
||||
|
||||
@@ -548,9 +548,9 @@ namespace FlaxEditor.Viewport
|
||||
#region Camera settings widget
|
||||
|
||||
var largestText = "Relative Panning";
|
||||
var textSize = Style.Current.FontMedium.MeasureText(largestText);
|
||||
var textSize = Style.Current.FontMedium.First().MeasureText(largestText);
|
||||
var xLocationForExtras = textSize.X + 5;
|
||||
var cameraSpeedTextWidth = Style.Current.FontMedium.MeasureText("0.00").X;
|
||||
var cameraSpeedTextWidth = Style.Current.FontMedium.First().MeasureText("0.00").X;
|
||||
|
||||
// Camera Settings Widget
|
||||
_cameraWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
@@ -801,7 +801,7 @@ namespace FlaxEditor.Viewport
|
||||
#region View mode widget
|
||||
|
||||
largestText = "Brightness";
|
||||
textSize = Style.Current.FontMedium.MeasureText(largestText);
|
||||
textSize = Style.Current.FontMedium.First().MeasureText(largestText);
|
||||
xLocationForExtras = textSize.X + 5;
|
||||
|
||||
var viewMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperLeft);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
@@ -162,8 +163,8 @@ namespace FlaxEditor.Viewport.Widgets
|
||||
{
|
||||
var style = Style.Current;
|
||||
|
||||
if (style != null && style.FontMedium)
|
||||
Width = CalculateButtonWidth(_forcedTextWidth > 0.0f ? _forcedTextWidth : style.FontMedium.MeasureText(_text).X, Icon.IsValid);
|
||||
if (style != null && style.FontMedium.First())
|
||||
Width = CalculateButtonWidth(_forcedTextWidth > 0.0f ? _forcedTextWidth : style.FontMedium.First().MeasureText(_text).X, Icon.IsValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.GUI.Dialogs;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
@@ -53,7 +54,7 @@ namespace FlaxEditor.Windows
|
||||
Parent = this
|
||||
};
|
||||
var buttonText = "Copy version info";
|
||||
var fontSize = Style.Current.FontMedium.MeasureText(buttonText);
|
||||
var fontSize = Style.Current.FontMedium.First().MeasureText(buttonText);
|
||||
var copyVersionButton = new Button(Width - fontSize.X - 8, 6, fontSize.X + 4, 20)
|
||||
{
|
||||
Text = buttonText,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEditor.Windows.Profiler
|
||||
{
|
||||
@@ -84,8 +85,8 @@ namespace FlaxEditor.Windows.Profiler
|
||||
Render2D.FillRectangle(bounds, color);
|
||||
Render2D.DrawRectangle(bounds, color * 0.5f);
|
||||
|
||||
if (_nameLength < 0 && style.FontMedium)
|
||||
_nameLength = style.FontMedium.MeasureText(_name).X;
|
||||
if (_nameLength < 0 && style.FontMedium.First())
|
||||
_nameLength = style.FontMedium.First().MeasureText(_name).X;
|
||||
|
||||
if (_nameLength < bounds.Width + 4)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.GUI.Input;
|
||||
using FlaxEditor.GUI.Tabs;
|
||||
using FlaxEditor.GUI.Tree;
|
||||
@@ -272,8 +273,8 @@ namespace FlaxEditor.Windows
|
||||
var textRect = item.TextRect;
|
||||
for (int i = 0; i < ranges.Length; i++)
|
||||
{
|
||||
var start = font.GetCharPosition(text, ranges[i].StartIndex);
|
||||
var end = font.GetCharPosition(text, ranges[i].EndIndex);
|
||||
var start = font.First().GetCharPosition(text, ranges[i].StartIndex);
|
||||
var end = font.First().GetCharPosition(text, ranges[i].EndIndex);
|
||||
highlights.Add(new Rectangle(start.X + textRect.X, textRect.Y, end.X - start.X, textRect.Height));
|
||||
}
|
||||
item.SetHighlights(highlights);
|
||||
|
||||
@@ -283,6 +283,206 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
|
||||
}
|
||||
}
|
||||
|
||||
void Font::ProcessText(const Array<Font*>& fonts, const StringView& text, Array<FontLineCache>& outputLines, API_PARAM(Ref) const TextLayoutOptions& layout)
|
||||
{
|
||||
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 baseLinesDistanceScale = layout.BaseLinesGapScale * scale;
|
||||
tmpLine.Location = Float2::Zero;
|
||||
tmpLine.Size = Float2::Zero;
|
||||
tmpLine.FirstCharIndex = 0;
|
||||
tmpLine.LastCharIndex = -1;
|
||||
|
||||
int32 lastWrapCharIndex = INVALID_INDEX;
|
||||
float lastWrapCharX = 0;
|
||||
bool lastMoveLine = false;
|
||||
|
||||
int32 previousFontIndex = -1;
|
||||
// The maximum font height of the current line
|
||||
float maxHeight = 0;
|
||||
// Process each character to split text into single lines
|
||||
for (int32 currentIndex = 0; currentIndex < textLength;)
|
||||
{
|
||||
bool moveLine = false;
|
||||
float xAdvance = 0;
|
||||
int32 nextCharIndex = currentIndex + 1;
|
||||
|
||||
// Cache current character
|
||||
const Char currentChar = text[currentIndex];
|
||||
const bool isWhitespace = StringUtils::IsWhitespace(currentChar);
|
||||
|
||||
// Check if character can wrap words
|
||||
const bool isWrapChar = !StringUtils::IsAlnum(currentChar) || isWhitespace || StringUtils::IsUpper(currentChar);
|
||||
if (isWrapChar && currentIndex != 0)
|
||||
{
|
||||
lastWrapCharIndex = currentIndex;
|
||||
lastWrapCharX = cursorX;
|
||||
}
|
||||
|
||||
// Check if it's a newline character
|
||||
if (currentChar == '\n')
|
||||
{
|
||||
// Break line
|
||||
moveLine = true;
|
||||
currentIndex++;
|
||||
tmpLine.LastCharIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get character entry
|
||||
int32 fontIndex = 0;
|
||||
while (fontIndex < fonts.Count() && !fonts[fontIndex]->ContainsChar(currentChar))
|
||||
{
|
||||
fontIndex++;
|
||||
}
|
||||
|
||||
// If no font can match the char, then use the first font
|
||||
if (fontIndex == fonts.Count()) {
|
||||
fontIndex = 0;
|
||||
}
|
||||
// Get character entry
|
||||
fonts[fontIndex]->GetCharacter(currentChar, entry);
|
||||
maxHeight = Math::Max(maxHeight, static_cast<float>(fonts[fontIndex]->GetHeight()));
|
||||
|
||||
// Get kerning, only when the font hasn't changed
|
||||
if (!isWhitespace && previous.IsValid && previousFontIndex == fontIndex)
|
||||
{
|
||||
kerning = fonts[fontIndex]->GetKerning(previous.Character, entry.Character);
|
||||
}
|
||||
else
|
||||
{
|
||||
kerning = 0;
|
||||
}
|
||||
previous = entry;
|
||||
previousFontIndex = fontIndex;
|
||||
xAdvance = (kerning + entry.AdvanceX) * scale;
|
||||
|
||||
// Check if character fits the line or skip wrapping
|
||||
if (cursorX + xAdvance <= boundsWidth || layout.TextWrapping == TextWrapping::NoWrap)
|
||||
{
|
||||
// Move character
|
||||
cursorX += xAdvance;
|
||||
tmpLine.LastCharIndex++;
|
||||
}
|
||||
else if (layout.TextWrapping == TextWrapping::WrapWords)
|
||||
{
|
||||
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)
|
||||
{
|
||||
currentIndex = nextCharIndex;
|
||||
lastMoveLine = moveLine;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Move line
|
||||
const Char wrapChar = text[lastWrapCharIndex];
|
||||
moveLine = true;
|
||||
cursorX = lastWrapCharX;
|
||||
if (StringUtils::IsWhitespace(wrapChar))
|
||||
{
|
||||
// Skip whitespaces
|
||||
tmpLine.LastCharIndex = lastWrapCharIndex - 1;
|
||||
nextCharIndex = currentIndex = lastWrapCharIndex + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpLine.LastCharIndex = lastWrapCharIndex - 1;
|
||||
nextCharIndex = currentIndex = lastWrapCharIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (layout.TextWrapping == TextWrapping::WrapChars)
|
||||
{
|
||||
// Move line
|
||||
moveLine = true;
|
||||
nextCharIndex = currentIndex;
|
||||
|
||||
// Skip moving twice for the same character
|
||||
if (lastMoveLine)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if move to another line
|
||||
if (moveLine)
|
||||
{
|
||||
// Add line
|
||||
tmpLine.Size.X = cursorX;
|
||||
tmpLine.Size.Y = baseLinesDistanceScale * maxHeight;
|
||||
tmpLine.LastCharIndex = Math::Max(tmpLine.LastCharIndex, tmpLine.FirstCharIndex);
|
||||
outputLines.Add(tmpLine);
|
||||
|
||||
// Reset line
|
||||
tmpLine.Location.Y += baseLinesDistanceScale * maxHeight;
|
||||
tmpLine.FirstCharIndex = currentIndex;
|
||||
tmpLine.LastCharIndex = currentIndex - 1;
|
||||
cursorX = 0;
|
||||
lastWrapCharIndex = INVALID_INDEX;
|
||||
lastWrapCharX = 0;
|
||||
previous.IsValid = false;
|
||||
|
||||
// Reset max font height
|
||||
maxHeight = 0;
|
||||
}
|
||||
|
||||
currentIndex = nextCharIndex;
|
||||
lastMoveLine = moveLine;
|
||||
}
|
||||
|
||||
if (textLength != 0 && (tmpLine.LastCharIndex >= tmpLine.FirstCharIndex || text[textLength - 1] == '\n'))
|
||||
{
|
||||
// Add line
|
||||
tmpLine.Size.X = cursorX;
|
||||
tmpLine.Size.Y = baseLinesDistanceScale * maxHeight;
|
||||
tmpLine.LastCharIndex = textLength - 1;
|
||||
outputLines.Add(tmpLine);
|
||||
|
||||
tmpLine.Location.Y += baseLinesDistanceScale * maxHeight;
|
||||
}
|
||||
|
||||
// Check amount of lines
|
||||
if (outputLines.IsEmpty())
|
||||
return;
|
||||
|
||||
float totalHeight = tmpLine.Location.Y;
|
||||
|
||||
Float2 offset = Float2::Zero;
|
||||
if (layout.VerticalAlignment == TextAlignment::Center)
|
||||
{
|
||||
offset.Y += (layout.Bounds.GetHeight() - totalHeight) * 0.5f;
|
||||
}
|
||||
else if (layout.VerticalAlignment == TextAlignment::Far)
|
||||
{
|
||||
offset.Y += layout.Bounds.GetHeight() - totalHeight;
|
||||
}
|
||||
for (int32 i = 0; i < outputLines.Count(); i++)
|
||||
{
|
||||
FontLineCache& line = outputLines[i];
|
||||
Float2 rootPos = line.Location + offset;
|
||||
|
||||
// Fix upper left line corner to match desire text alignment
|
||||
if (layout.HorizontalAlignment == TextAlignment::Center)
|
||||
{
|
||||
rootPos.X += (layout.Bounds.GetWidth() - line.Size.X) * 0.5f;
|
||||
}
|
||||
else if (layout.HorizontalAlignment == TextAlignment::Far)
|
||||
{
|
||||
rootPos.X += layout.Bounds.GetWidth() - line.Size.X;
|
||||
}
|
||||
|
||||
line.Location = rootPos;
|
||||
}
|
||||
}
|
||||
|
||||
Float2 Font::MeasureText(const StringView& text, const TextLayoutOptions& layout)
|
||||
{
|
||||
// Check if there is no need to do anything
|
||||
@@ -432,6 +632,11 @@ Float2 Font::GetCharPosition(const StringView& text, int32 index, const TextLayo
|
||||
return rootOffset + Float2(lines.Last().Size.X, static_cast<float>((lines.Count() - 1) * baseLinesDistance));
|
||||
}
|
||||
|
||||
bool Font::ContainsChar(Char c)
|
||||
{
|
||||
return FT_Get_Char_Index(GetAsset()->GetFTFace(), c) > 0;
|
||||
}
|
||||
|
||||
void Font::FlushFaceSize() const
|
||||
{
|
||||
// Set the character size
|
||||
|
||||
@@ -339,6 +339,15 @@ public:
|
||||
/// <param name="outputLines">The output lines list.</param>
|
||||
void ProcessText(const StringView& text, Array<FontLineCache>& outputLines, API_PARAM(Ref) const TextLayoutOptions& layout);
|
||||
|
||||
/// <summary>
|
||||
/// Processes text to get cached lines for rendering.
|
||||
/// </summary>
|
||||
/// <param name="fonts">The font list.</param>
|
||||
/// <param name="text">The input text.</param>
|
||||
/// <param name="layout">The layout properties.</param>
|
||||
/// <param name="outputLines">The output lines list.</param>
|
||||
static void ProcessText(const Array<Font*>& fonts, const StringView& text, Array<FontLineCache>& outputLines, API_PARAM(Ref) const TextLayoutOptions& layout);
|
||||
|
||||
/// <summary>
|
||||
/// Processes text to get cached lines for rendering.
|
||||
/// </summary>
|
||||
@@ -395,6 +404,15 @@ public:
|
||||
/// <returns>The minimum size for that text and fot to render properly.</returns>
|
||||
API_FUNCTION() Float2 MeasureText(const StringView& text, API_PARAM(Ref) const TextLayoutOptions& layout);
|
||||
|
||||
/// <summary>
|
||||
/// Measures minimum size of the rectangle that will be needed to draw given text.
|
||||
/// </summary>
|
||||
/// <param name="fonts">The fonts to render with.</param>
|
||||
/// <param name="text">The input text to test.</param>
|
||||
/// <param name="layout">The layout properties.</param>
|
||||
/// <returns>The minimum size for that text and fot to render properly.</returns>
|
||||
API_FUNCTION() static Float2 MeasureText(const Array<Font*>& fonts, const StringView& text, API_PARAM(Ref) const TextLayoutOptions& layout);
|
||||
|
||||
/// <summary>
|
||||
/// Measures minimum size of the rectangle that will be needed to draw given text.
|
||||
/// </summary>
|
||||
@@ -482,6 +500,16 @@ public:
|
||||
/// <returns>The character position (upper left corner which can be used for a caret position).</returns>
|
||||
API_FUNCTION() Float2 GetCharPosition(const StringView& text, int32 index, API_PARAM(Ref) const TextLayoutOptions& layout);
|
||||
|
||||
/// <summary>
|
||||
/// Calculates character position for given text and character index.
|
||||
/// </summary>
|
||||
/// <param name="fonts">The fonts to use.</param>
|
||||
/// <param name="text">The input text to test.</param>
|
||||
/// <param name="index">The text position to get coordinates of.</param>
|
||||
/// <param name="layout">The text layout properties.</param>
|
||||
/// <returns>The character position (upper left corner which can be used for a caret position).</returns>
|
||||
API_FUNCTION() static Float2 GetCharPosition(const Array<Font*>& fonts, const StringView& text, int32 index, API_PARAM(Ref) const TextLayoutOptions& layout);
|
||||
|
||||
/// <summary>
|
||||
/// Calculates character position for given text and character index.
|
||||
/// </summary>
|
||||
@@ -518,6 +546,13 @@ public:
|
||||
return GetCharPosition(textRange.Substring(text), index, TextLayoutOptions());
|
||||
}
|
||||
|
||||
/// <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() FORCE_INLINE bool ContainsChar(Char c);
|
||||
|
||||
/// <summary>
|
||||
/// Flushes the size of the face with the Free Type library backend.
|
||||
/// </summary>
|
||||
|
||||
@@ -155,6 +155,9 @@ 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 (glyphIndex == 0) {
|
||||
LOG(Warning, "Font `{}` doesn't contain character `\\u{:x}`, consider choosing another font. ", String(face->family_name), c);
|
||||
}
|
||||
|
||||
// Load the glyph
|
||||
const FT_Error error = FT_Load_Glyph(face, glyphIndex, glyphFlags);
|
||||
|
||||
@@ -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
|
||||
@@ -54,7 +54,7 @@ const bool DownsampleForBlur = false;
|
||||
|
||||
PACK_STRUCT(struct Data {
|
||||
Matrix ViewProjection;
|
||||
});
|
||||
});
|
||||
|
||||
PACK_STRUCT(struct BlurData {
|
||||
Float2 InvBufferSize;
|
||||
@@ -62,7 +62,7 @@ PACK_STRUCT(struct BlurData {
|
||||
float Dummy0;
|
||||
Float4 Bounds;
|
||||
Float4 WeightAndOffsets[RENDER2D_BLUR_MAX_SAMPLES / 2];
|
||||
});
|
||||
});
|
||||
|
||||
enum class DrawCallType : byte
|
||||
{
|
||||
@@ -1174,7 +1174,7 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
|
||||
drawCall.AsChar.Mat = nullptr;
|
||||
}
|
||||
Float2 pointer = location;
|
||||
for (int32 currentIndex = 0; currentIndex <= text.Length(); currentIndex++)
|
||||
for (int32 currentIndex = 0; currentIndex < text.Length(); currentIndex++)
|
||||
{
|
||||
// Cache current character
|
||||
const Char currentChar = text[currentIndex];
|
||||
@@ -1368,6 +1368,318 @@ void Render2D::DrawText(Font* font, const StringView& text, const TextRange& tex
|
||||
DrawText(font, textRange.Substring(text), color, layout, customMaterial);
|
||||
}
|
||||
|
||||
void Render2D::DrawText(const Array<Font*>& fonts, const StringView& text, const Color& color, const Float2& location, MaterialBase* customMaterial)
|
||||
{
|
||||
RENDER2D_CHECK_RENDERING_STATE;
|
||||
|
||||
// Check if there is no need to do anything
|
||||
if (fonts.IsEmpty() || text.Length() < 0)
|
||||
return;
|
||||
|
||||
// Temporary data
|
||||
uint32 fontAtlasIndex = 0;
|
||||
FontTextureAtlas* fontAtlas = nullptr;
|
||||
Float2 invAtlasSize = Float2::One;
|
||||
FontCharacterEntry previous;
|
||||
int32 kerning;
|
||||
float scale = 1.0f / FontManager::FontScale;
|
||||
|
||||
// Render all characters
|
||||
FontCharacterEntry entry;
|
||||
Render2DDrawCall drawCall;
|
||||
if (customMaterial)
|
||||
{
|
||||
drawCall.Type = DrawCallType::DrawCharMaterial;
|
||||
drawCall.AsChar.Mat = customMaterial;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawCall.Type = DrawCallType::DrawChar;
|
||||
drawCall.AsChar.Mat = nullptr;
|
||||
}
|
||||
|
||||
// The following code cut the text into segments, according to the font used to render
|
||||
Float2 pointer = location;
|
||||
// The starting index of the current segment
|
||||
int32 startIndex = 0;
|
||||
// The index of the font used by the current segment
|
||||
int32 segmentFontIndex = 0;
|
||||
// The maximum font height of the current line
|
||||
float maxHeight = 0;
|
||||
for (int32 currentIndex = 0; currentIndex <= text.Length(); currentIndex++)
|
||||
{
|
||||
// Cache current character
|
||||
const Char currentChar = currentIndex < text.Length() ? text[currentIndex] : 0;
|
||||
|
||||
// Check if it isn't a newline character
|
||||
if (currentChar != '\n')
|
||||
{
|
||||
int32 fontIndex = 0;
|
||||
if (currentIndex < text.Length()) {
|
||||
while (fontIndex < fonts.Count() && !fonts[fontIndex]->ContainsChar(currentChar))
|
||||
{
|
||||
fontIndex++;
|
||||
}
|
||||
|
||||
// If no font can match the char, then use the segment font
|
||||
if (fontIndex == fonts.Count()) {
|
||||
fontIndex = segmentFontIndex;
|
||||
}
|
||||
|
||||
// Do nothing if the char still belongs to the current segment
|
||||
if (fontIndex == segmentFontIndex) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Render the pending segment before beginning the new segment
|
||||
renderText:auto fontHeight = fonts[segmentFontIndex]->GetHeight();
|
||||
maxHeight = Math::Max(maxHeight, static_cast<float>(fontHeight));
|
||||
auto fontDescender = fonts[segmentFontIndex]->GetDescender();
|
||||
for (int32 renderIndex = startIndex; renderIndex < currentIndex; renderIndex++)
|
||||
{
|
||||
// Get character entry
|
||||
fonts[segmentFontIndex]->GetCharacter(text[renderIndex], entry);
|
||||
|
||||
// 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)
|
||||
{
|
||||
// Get texture atlas that contains current character
|
||||
fontAtlasIndex = entry.TextureIndex;
|
||||
fontAtlas = FontManager::GetAtlas(fontAtlasIndex);
|
||||
if (fontAtlas)
|
||||
{
|
||||
fontAtlas->EnsureTextureCreated();
|
||||
drawCall.AsChar.Tex = fontAtlas->GetTexture();
|
||||
invAtlasSize = 1.0f / fontAtlas->GetSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
drawCall.AsChar.Tex = nullptr;
|
||||
invAtlasSize = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if character is a whitespace
|
||||
const bool isWhitespace = StringUtils::IsWhitespace(text[renderIndex]);
|
||||
|
||||
// Get kerning
|
||||
if (!isWhitespace && previous.IsValid)
|
||||
{
|
||||
kerning = fonts[segmentFontIndex]->GetKerning(previous.Character, entry.Character);
|
||||
}
|
||||
else
|
||||
{
|
||||
kerning = 0;
|
||||
}
|
||||
pointer.X += kerning * scale;
|
||||
previous = entry;
|
||||
|
||||
// Omit whitespace characters
|
||||
if (!isWhitespace)
|
||||
{
|
||||
// Calculate character size and atlas coordinates
|
||||
const float x = pointer.X + entry.OffsetX * scale;
|
||||
const float y = pointer.Y + (fontHeight + fontDescender - entry.OffsetY) * scale;
|
||||
|
||||
Rectangle charRect(x, y, entry.UVSize.X * scale, entry.UVSize.Y * scale);
|
||||
|
||||
Float2 upperLeftUV = entry.UV * invAtlasSize;
|
||||
Float2 rightBottomUV = (entry.UV + entry.UVSize) * invAtlasSize;
|
||||
|
||||
// Add draw call
|
||||
drawCall.StartIB = IBIndex;
|
||||
drawCall.CountIB = 6;
|
||||
DrawCalls.Add(drawCall);
|
||||
WriteRect(charRect, color, upperLeftUV, rightBottomUV);
|
||||
}
|
||||
|
||||
// Move
|
||||
pointer.X += entry.AdvanceX * scale;
|
||||
}
|
||||
|
||||
// Start new segment
|
||||
startIndex = currentIndex;
|
||||
segmentFontIndex = fontIndex;
|
||||
|
||||
if (currentIndex == text.Length() - 1) {
|
||||
currentIndex++;
|
||||
goto renderText;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move
|
||||
pointer.X = location.X;
|
||||
pointer.Y += maxHeight * scale;
|
||||
// Clear max height
|
||||
maxHeight = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Render2D::DrawText(const Array<Font*>& fonts, const StringView& text, const TextRange& textRange, const Color& color, const Float2& location, MaterialBase* customMaterial)
|
||||
{
|
||||
DrawText(fonts, textRange.Substring(text), color, location, customMaterial);
|
||||
}
|
||||
|
||||
void Render2D::DrawText(const Array<Font*>& fonts, const StringView& text, const Color& color, const TextLayoutOptions& layout, MaterialBase* customMaterial)
|
||||
{
|
||||
RENDER2D_CHECK_RENDERING_STATE;
|
||||
|
||||
// Check if there is no need to do anything
|
||||
if (fonts.IsEmpty() || text.IsEmpty() || layout.Scale <= ZeroTolerance)
|
||||
return;
|
||||
|
||||
// Temporary data
|
||||
uint32 fontAtlasIndex = 0;
|
||||
FontTextureAtlas* fontAtlas = nullptr;
|
||||
Float2 invAtlasSize = Float2::One;
|
||||
FontCharacterEntry previous;
|
||||
int32 kerning;
|
||||
float scale = layout.Scale / FontManager::FontScale;
|
||||
|
||||
// Process text to get lines
|
||||
Lines.Clear();
|
||||
Font::ProcessText(fonts, text, Lines, layout);
|
||||
|
||||
// Render all lines
|
||||
FontCharacterEntry entry;
|
||||
Render2DDrawCall drawCall;
|
||||
if (customMaterial)
|
||||
{
|
||||
drawCall.Type = DrawCallType::DrawCharMaterial;
|
||||
drawCall.AsChar.Mat = customMaterial;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawCall.Type = DrawCallType::DrawChar;
|
||||
drawCall.AsChar.Mat = nullptr;
|
||||
}
|
||||
|
||||
for (int32 lineIndex = 0; lineIndex < Lines.Count(); lineIndex++)
|
||||
{
|
||||
const FontLineCache& line = Lines[lineIndex];
|
||||
|
||||
// The following code cut the text into segments, according to the font used to render
|
||||
Float2 pointer = line.Location;
|
||||
// The starting index of the current segment
|
||||
int32 startIndex = line.FirstCharIndex;
|
||||
// The index of the font used by the current segment
|
||||
int32 segmentFontIndex = 0;
|
||||
// The maximum font height of the current line
|
||||
float maxHeight = 0;
|
||||
|
||||
// Partition and render all characters from the line
|
||||
for (int32 charIndex = line.FirstCharIndex; charIndex <= line.LastCharIndex + 1; charIndex++)
|
||||
{
|
||||
const Char c = charIndex <= line.LastCharIndex ? text[charIndex] : 0;
|
||||
|
||||
if (c != '\n')
|
||||
{
|
||||
int32 fontIndex = 0;
|
||||
if (charIndex <= line.LastCharIndex) {
|
||||
while (fontIndex < fonts.Count() && !fonts[fontIndex]->ContainsChar(c))
|
||||
{
|
||||
fontIndex++;
|
||||
}
|
||||
|
||||
// If no font can match the char, then use the segment font
|
||||
if (fontIndex == fonts.Count()) {
|
||||
fontIndex = segmentFontIndex;
|
||||
}
|
||||
|
||||
|
||||
// Do nothing if the char still belongs to the current segment
|
||||
if (fontIndex == segmentFontIndex) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Render the pending segment before beginning the new segment
|
||||
auto fontHeight = fonts[segmentFontIndex]->GetHeight();
|
||||
maxHeight = Math::Max(maxHeight, static_cast<float>(fontHeight));
|
||||
auto fontDescender = fonts[segmentFontIndex]->GetDescender();
|
||||
|
||||
const Char* pred = L"Type";
|
||||
if (text.Substring(0, Math::Min(4, text.Length())) == pred) {
|
||||
// __debugbreak();
|
||||
}
|
||||
for (int32 renderIndex = startIndex; renderIndex < charIndex; renderIndex++)
|
||||
{
|
||||
// Get character entry
|
||||
fonts[segmentFontIndex]->GetCharacter(text[renderIndex], entry);
|
||||
|
||||
// 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)
|
||||
{
|
||||
// Get texture atlas that contains current character
|
||||
fontAtlasIndex = entry.TextureIndex;
|
||||
fontAtlas = FontManager::GetAtlas(fontAtlasIndex);
|
||||
if (fontAtlas)
|
||||
{
|
||||
fontAtlas->EnsureTextureCreated();
|
||||
invAtlasSize = 1.0f / fontAtlas->GetSize();
|
||||
drawCall.AsChar.Tex = fontAtlas->GetTexture();
|
||||
}
|
||||
else
|
||||
{
|
||||
invAtlasSize = 1.0f;
|
||||
drawCall.AsChar.Tex = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Get kerning
|
||||
const bool isWhitespace = StringUtils::IsWhitespace(text[renderIndex]);
|
||||
if (!isWhitespace && previous.IsValid)
|
||||
{
|
||||
kerning = fonts[segmentFontIndex]->GetKerning(previous.Character, entry.Character);
|
||||
}
|
||||
else
|
||||
{
|
||||
kerning = 0;
|
||||
}
|
||||
pointer.X += (float)kerning * scale;
|
||||
previous = entry;
|
||||
|
||||
// Omit whitespace characters
|
||||
if (!isWhitespace)
|
||||
{
|
||||
// Calculate character size and atlas coordinates
|
||||
const float x = pointer.X + entry.OffsetX * scale;
|
||||
const float y = pointer.Y - entry.OffsetY * scale + Math::Ceil((fontHeight + fontDescender) * scale);
|
||||
|
||||
Rectangle charRect(x, y, entry.UVSize.X * scale, entry.UVSize.Y * scale);
|
||||
charRect.Offset(layout.Bounds.Location);
|
||||
|
||||
Float2 upperLeftUV = entry.UV * invAtlasSize;
|
||||
Float2 rightBottomUV = (entry.UV + entry.UVSize) * invAtlasSize;
|
||||
|
||||
// Add draw call
|
||||
drawCall.StartIB = IBIndex;
|
||||
drawCall.CountIB = 6;
|
||||
DrawCalls.Add(drawCall);
|
||||
WriteRect(charRect, color, upperLeftUV, rightBottomUV);
|
||||
}
|
||||
|
||||
// Move
|
||||
pointer.X += entry.AdvanceX * scale;
|
||||
}
|
||||
|
||||
// Start new segment
|
||||
startIndex = charIndex;
|
||||
segmentFontIndex = fontIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Render2D::DrawText(const Array<Font*>& fonts, const StringView& text, const TextRange& textRange, const Color& color, const TextLayoutOptions& layout, MaterialBase* customMaterial)
|
||||
{
|
||||
DrawText(fonts, textRange.Substring(text), color, layout, customMaterial);
|
||||
}
|
||||
|
||||
FORCE_INLINE bool NeedAlphaWithTint(const Color& color)
|
||||
{
|
||||
return (color.A * TintLayersStack.Peek().A) < 1.0f;
|
||||
@@ -1931,7 +2243,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 +2289,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++];
|
||||
|
||||
@@ -152,6 +152,59 @@ namespace FlaxEngine
|
||||
DrawText(font, text, color, ref layout, customMaterial);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a text.
|
||||
/// </summary>
|
||||
/// <param name="fonts">The fonts to use, ordered by priority.</param>
|
||||
/// <param name="text">The text to render.</param>
|
||||
/// <param name="layoutRect">The size and position of the area in which the text is drawn.</param>
|
||||
/// <param name="color">The text color.</param>
|
||||
/// <param name="horizontalAlignment">The horizontal alignment of the text in a layout rectangle.</param>
|
||||
/// <param name="verticalAlignment">The vertical alignment of the text in a layout rectangle.</param>
|
||||
/// <param name="textWrapping">Describes how wrap text inside a layout rectangle.</param>
|
||||
/// <param name="baseLinesGapScale">The scale for distance one baseline from another. Default is 1.</param>
|
||||
/// <param name="scale">The text drawing scale. Default is 1.</param>
|
||||
public static void DrawText(Font[] fonts, string text, Rectangle layoutRect, Color color, TextAlignment horizontalAlignment = TextAlignment.Near, TextAlignment verticalAlignment = TextAlignment.Near, TextWrapping textWrapping = TextWrapping.NoWrap, float baseLinesGapScale = 1.0f, float scale = 1.0f)
|
||||
{
|
||||
var layout = new TextLayoutOptions
|
||||
{
|
||||
Bounds = layoutRect,
|
||||
HorizontalAlignment = horizontalAlignment,
|
||||
VerticalAlignment = verticalAlignment,
|
||||
TextWrapping = textWrapping,
|
||||
Scale = scale,
|
||||
BaseLinesGapScale = baseLinesGapScale,
|
||||
};
|
||||
DrawText(fonts, text, color, ref layout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a text using a custom material shader. Given material must have GUI domain and a public parameter named Font (texture parameter used for a font atlas sampling).
|
||||
/// </summary>
|
||||
/// <param name="fonts">The fonts to use, ordered by priority.</param>
|
||||
/// <param name="customMaterial">Custom material for font characters rendering. It must contain texture parameter named Font used to sample font texture.</param>
|
||||
/// <param name="text">The text to render.</param>
|
||||
/// <param name="layoutRect">The size and position of the area in which the text is drawn.</param>
|
||||
/// <param name="color">The text color.</param>
|
||||
/// <param name="horizontalAlignment">The horizontal alignment of the text in a layout rectangle.</param>
|
||||
/// <param name="verticalAlignment">The vertical alignment of the text in a layout rectangle.</param>
|
||||
/// <param name="textWrapping">Describes how wrap text inside a layout rectangle.</param>
|
||||
/// <param name="baseLinesGapScale">The scale for distance one baseline from another. Default is 1.</param>
|
||||
/// <param name="scale">The text drawing scale. Default is 1.</param>
|
||||
public static void DrawText(Font[] fonts, MaterialBase customMaterial, string text, Rectangle layoutRect, Color color, TextAlignment horizontalAlignment = TextAlignment.Near, TextAlignment verticalAlignment = TextAlignment.Near, TextWrapping textWrapping = TextWrapping.NoWrap, float baseLinesGapScale = 1.0f, float scale = 1.0f)
|
||||
{
|
||||
var layout = new TextLayoutOptions
|
||||
{
|
||||
Bounds = layoutRect,
|
||||
HorizontalAlignment = horizontalAlignment,
|
||||
VerticalAlignment = verticalAlignment,
|
||||
TextWrapping = textWrapping,
|
||||
Scale = scale,
|
||||
BaseLinesGapScale = baseLinesGapScale,
|
||||
};
|
||||
DrawText(fonts, text, color, ref layout, customMaterial);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls drawing GUI to the texture.
|
||||
/// </summary>
|
||||
|
||||
@@ -33,7 +33,7 @@ API_CLASS(Static) class FLAXENGINE_API Render2D
|
||||
/// <summary>
|
||||
/// The rendering features and options flags.
|
||||
/// </summary>
|
||||
API_ENUM(Attributes="Flags") enum class RenderingFeatures
|
||||
API_ENUM(Attributes = "Flags") enum class RenderingFeatures
|
||||
{
|
||||
/// <summary>
|
||||
/// The none.
|
||||
@@ -215,6 +215,49 @@ public:
|
||||
/// <param name="customMaterial">The custom material for font characters rendering. It must contain texture parameter named Font used to sample font texture.</param>
|
||||
API_FUNCTION() static void DrawText(Font* font, const StringView& text, API_PARAM(Ref) const TextRange& textRange, const Color& color, API_PARAM(Ref) const TextLayoutOptions& layout, MaterialBase* customMaterial = nullptr);
|
||||
|
||||
/// <summary>
|
||||
/// Draws a text.
|
||||
/// </summary>
|
||||
/// <param name="fonts">The fonts to use, ordered by priority.</param>
|
||||
/// <param name="text">The text to render.</param>
|
||||
/// <param name="textRange">The input text range (substring range of the input text parameter).</param>
|
||||
/// <param name="color">The text color.</param>
|
||||
/// <param name="location">The text location.</param>
|
||||
/// <param name="customMaterial">The custom material for font characters rendering. It must contain texture parameter named Font used to sample font texture.</param>
|
||||
API_FUNCTION() static void DrawText(const Array<Font*, HeapAllocation>& fonts, const StringView& text, const Color& color, const Float2& location, MaterialBase* customMaterial = nullptr);
|
||||
|
||||
/// <summary>
|
||||
/// Draws a text with formatting.
|
||||
/// </summary>
|
||||
/// <param name="fonts">The fonts to use, ordered by priority.</param>
|
||||
/// <param name="text">The text to render.</param>
|
||||
/// <param name="color">The text color.</param>
|
||||
/// <param name="layout">The text layout properties.</param>
|
||||
/// <param name="customMaterial">The custom material for font characters rendering. It must contain texture parameter named Font used to sample font texture.</param>
|
||||
API_FUNCTION() static void DrawText(const Array<Font*, HeapAllocation>& fonts, const StringView& text, API_PARAM(Ref) const TextRange& textRange, const Color& color, const Float2& location, MaterialBase* customMaterial = nullptr);
|
||||
|
||||
/// <summary>
|
||||
/// Draws a text with formatting.
|
||||
/// </summary>
|
||||
/// <param name="fonts">The fonts to use, ordered by priority.</param>
|
||||
/// <param name="text">The text to render.</param>
|
||||
/// <param name="textRange">The input text range (substring range of the input text parameter).</param>
|
||||
/// <param name="color">The text color.</param>
|
||||
/// <param name="layout">The text layout properties.</param>
|
||||
/// <param name="customMaterial">The custom material for font characters rendering. It must contain texture parameter named Font used to sample font texture.</param>
|
||||
API_FUNCTION() static void DrawText(const Array<Font*, HeapAllocation>& fonts, const StringView& text, const Color& color, API_PARAM(Ref) const TextLayoutOptions& layout, MaterialBase* customMaterial = nullptr);
|
||||
|
||||
/// <summary>
|
||||
/// Draws a text with formatting.
|
||||
/// </summary>
|
||||
/// <param name="fonts">The fonts to use, ordered by priority.</param>
|
||||
/// <param name="text">The text to render.</param>
|
||||
/// <param name="textRange">The input text range (substring range of the input text parameter).</param>
|
||||
/// <param name="color">The text color.</param>
|
||||
/// <param name="layout">The text layout properties.</param>
|
||||
/// <param name="customMaterial">The custom material for font characters rendering. It must contain texture parameter named Font used to sample font texture.</param>
|
||||
API_FUNCTION() static void DrawText(const Array<Font*, HeapAllocation>& fonts, const StringView& text, API_PARAM(Ref) const TextRange& textRange, const Color& color, API_PARAM(Ref) const TextLayoutOptions& layout, MaterialBase* customMaterial = nullptr);
|
||||
|
||||
/// <summary>
|
||||
/// Fills a rectangle area.
|
||||
/// </summary>
|
||||
|
||||
@@ -295,12 +295,13 @@ namespace FlaxEngine
|
||||
|
||||
// Use optionally bundled default font (matches Editor)
|
||||
var defaultFont = Content.LoadAsyncInternal<FontAsset>("Editor/Fonts/Roboto-Regular");
|
||||
var cjkFont = Content.LoadAsyncInternal<FontAsset>("NotoSansSC-Medium");
|
||||
if (defaultFont)
|
||||
{
|
||||
style.FontTitle = defaultFont.CreateFont(18);
|
||||
style.FontLarge = defaultFont.CreateFont(14);
|
||||
style.FontMedium = defaultFont.CreateFont(9);
|
||||
style.FontSmall = defaultFont.CreateFont(9);
|
||||
style.FontMedium = new Font[] { defaultFont.CreateFont(9), cjkFont.CreateFont(9) };
|
||||
style.FontSmall = new Font[] { defaultFont.CreateFont(9), cjkFont.CreateFont(9) };
|
||||
}
|
||||
|
||||
Style.Current = style;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEngine.GUI
|
||||
{
|
||||
@@ -155,7 +156,7 @@ namespace FlaxEngine.GUI
|
||||
var style = Style.Current;
|
||||
if (style != null)
|
||||
{
|
||||
_font = new FontReference(style.FontMedium);
|
||||
_font = new FontReference(style.FontMedium.First());
|
||||
TextColor = style.Foreground;
|
||||
BackgroundColor = style.BackgroundNormal;
|
||||
BorderColor = style.BorderNormal;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEngine.GUI
|
||||
{
|
||||
@@ -358,7 +359,7 @@ namespace FlaxEngine.GUI
|
||||
: base(0, 0, 120, 18.0f)
|
||||
{
|
||||
var style = Style.Current;
|
||||
Font = new FontReference(style.FontMedium);
|
||||
Font = new FontReference(style.FontMedium.First());
|
||||
TextColor = style.Foreground;
|
||||
BackgroundColor = style.BackgroundNormal;
|
||||
BackgroundColorHighlighted = BackgroundColor;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using FlaxEditor.Options;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEngine.GUI
|
||||
{
|
||||
@@ -190,7 +192,7 @@ namespace FlaxEngine.GUI
|
||||
{
|
||||
AutoFocus = false;
|
||||
var style = Style.Current;
|
||||
Font = new FontReference(style.FontMedium);
|
||||
Font = new FontReference(style.FontMedium.First());
|
||||
TextColor = style.Foreground;
|
||||
TextColorHighlighted = style.Foreground;
|
||||
}
|
||||
@@ -201,7 +203,7 @@ namespace FlaxEngine.GUI
|
||||
{
|
||||
AutoFocus = false;
|
||||
var style = Style.Current;
|
||||
Font = new FontReference(style.FontMedium);
|
||||
Font = new FontReference(style.FontMedium.First());
|
||||
TextColor = style.Foreground;
|
||||
TextColorHighlighted = style.Foreground;
|
||||
}
|
||||
@@ -233,7 +235,7 @@ namespace FlaxEngine.GUI
|
||||
}
|
||||
}
|
||||
|
||||
Render2D.DrawText(_font.GetFont(), Material, _text, rect, color, hAlignment, wAlignment, Wrapping, BaseLinesGapScale, scale);
|
||||
Render2D.DrawText(new Font[] { _font.GetFont(), Style.Current.FontCJK }, Material, _text, rect, color, hAlignment, wAlignment, Wrapping, BaseLinesGapScale, scale);
|
||||
|
||||
if (ClipText)
|
||||
Render2D.PopClip();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEngine.GUI
|
||||
{
|
||||
@@ -45,7 +46,7 @@ namespace FlaxEngine.GUI
|
||||
var style = Style.Current;
|
||||
_textStyle = new TextBlockStyle
|
||||
{
|
||||
Font = new FontReference(style.FontMedium),
|
||||
Font = new FontReference(style.FontMedium.First()),
|
||||
Color = style.Foreground,
|
||||
BackgroundSelectedBrush = new SolidColorBrush(style.BackgroundSelected),
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEngine.GUI
|
||||
{
|
||||
/// <summary>
|
||||
@@ -88,7 +90,7 @@ namespace FlaxEngine.GUI
|
||||
_layout.Bounds = new Rectangle(DefaultMargin, 1, Width - 2 * DefaultMargin, Height - 2);
|
||||
|
||||
var style = Style.Current;
|
||||
Font = new FontReference(style.FontMedium);
|
||||
Font = new FontReference(style.FontMedium.First());
|
||||
TextColor = style.Foreground;
|
||||
WatermarkTextColor = style.ForegroundDisabled;
|
||||
SelectionColor = style.BackgroundSelected;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEngine.GUI
|
||||
{
|
||||
@@ -237,7 +238,7 @@ namespace FlaxEngine.GUI
|
||||
var style = Style.Current;
|
||||
HeaderColor = style.BackgroundNormal;
|
||||
HeaderColorMouseOver = style.BackgroundHighlighted;
|
||||
HeaderTextFont = new FontReference(style.FontMedium);
|
||||
HeaderTextFont = new FontReference(style.FontMedium.First());
|
||||
HeaderTextColor = style.Foreground;
|
||||
ArrowImageOpened = new SpriteBrush(style.ArrowDown);
|
||||
ArrowImageClosed = new SpriteBrush(style.ArrowRight);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEngine.GUI
|
||||
{
|
||||
/// <summary>
|
||||
@@ -12,6 +14,14 @@ namespace FlaxEngine.GUI
|
||||
/// </summary>
|
||||
public static Style Current { get; set; }
|
||||
|
||||
public Font FontCJK
|
||||
{
|
||||
get => _fontCJK?.GetFont();
|
||||
set => _fontCJK = new FontReference(value);
|
||||
}
|
||||
|
||||
private FontReference _fontCJK;
|
||||
|
||||
[Serialize]
|
||||
private FontReference _fontTitle;
|
||||
|
||||
@@ -41,31 +51,31 @@ namespace FlaxEngine.GUI
|
||||
}
|
||||
|
||||
[Serialize]
|
||||
private FontReference _fontMedium;
|
||||
private FontReference[] _fontMedium;
|
||||
|
||||
/// <summary>
|
||||
/// The font medium.
|
||||
/// </summary>
|
||||
[NoSerialize]
|
||||
[EditorOrder(30)]
|
||||
public Font FontMedium
|
||||
public Font[] FontMedium
|
||||
{
|
||||
get => _fontMedium?.GetFont();
|
||||
set => _fontMedium = new FontReference(value);
|
||||
get => _fontMedium?.Select((x)=>x.GetFont()).ToArray();
|
||||
set => _fontMedium = value.Select((x)=>new FontReference(x)).ToArray();
|
||||
}
|
||||
|
||||
[Serialize]
|
||||
private FontReference _fontSmall;
|
||||
private FontReference[] _fontSmall;
|
||||
|
||||
/// <summary>
|
||||
/// The font small.
|
||||
/// </summary>
|
||||
[NoSerialize]
|
||||
[EditorOrder(40)]
|
||||
public Font FontSmall
|
||||
public Font[] FontSmall
|
||||
{
|
||||
get => _fontSmall?.GetFont();
|
||||
set => _fontSmall = new FontReference(value);
|
||||
get => _fontSmall?.Select((x) => x.GetFont()).ToArray();
|
||||
set => _fontSmall = value.Select((x) => new FontReference(x)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEngine.GUI
|
||||
{
|
||||
@@ -255,14 +256,14 @@ namespace FlaxEngine.GUI
|
||||
|
||||
// Calculate size of the tooltip
|
||||
var size = Float2.Zero;
|
||||
if (style != null && style.FontMedium && !string.IsNullOrEmpty(_currentText))
|
||||
if (style != null && style.FontMedium.First() && !string.IsNullOrEmpty(_currentText))
|
||||
{
|
||||
var layout = TextLayoutOptions.Default;
|
||||
layout.Bounds = new Rectangle(0, 0, MaxWidth, 10000000);
|
||||
layout.HorizontalAlignment = TextAlignment.Center;
|
||||
layout.VerticalAlignment = TextAlignment.Center;
|
||||
layout.TextWrapping = TextWrapping.WrapWords;
|
||||
var items = style.FontMedium.ProcessText(_currentText, ref layout);
|
||||
var items = style.FontMedium.First().ProcessText(_currentText, ref layout);
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
ref var item = ref items[i];
|
||||
|
||||
Reference in New Issue
Block a user