_font fixups

_font fixup

_font visject scaling fix

_font scaling dpi fixes

_font fix wrapping
This commit is contained in:
2024-02-18 22:28:30 +02:00
parent f29a014aec
commit 84da819f30
3 changed files with 28 additions and 59 deletions

View File

@@ -173,20 +173,20 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
if (textLength == 0)
return;
int32 cursorX = 0;
FontLineCache tmpLine;
FontLineCharacterCache characterCache;
Char previous = 0;
float scale = layout.Scale / FontManager::FontScale;
int32 boundsWidth = layout.Bounds.GetWidth() / scale;
int32 boundsWidth = (int32)Math::Ceil(layout.Bounds.GetWidth() / scale);
float baseLinesDistance = static_cast<float>(_height) * layout.BaseLinesGapScale * scale;
FontLineCache tmpLine;
tmpLine.Location = Float2::Zero;
tmpLine.Size = Float2::Zero;
tmpLine.FirstCharIndex = 0;
tmpLine.LastCharIndex = -1;
int32 lastWrapCharIndex = INVALID_INDEX;
int32 lastWrapCharX = 0;
bool lastMoveLine = false;
int32 newlinesCount = 0;
// Process each character to split text into single lines
for (int32 currentIndex = 0; currentIndex < textLength;)
@@ -213,6 +213,7 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
// Break line
moveLine = true;
currentIndex++;
newlinesCount++;
tmpLine.LastCharIndex++;
}
else
@@ -256,17 +257,11 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
const Char wrapChar = text[lastWrapCharIndex];
moveLine = true;
cursorX = lastWrapCharX;
tmpLine.LastCharIndex = lastWrapCharIndex;
if (StringUtils::IsWhitespace(wrapChar))
{
// Skip whitespaces
tmpLine.LastCharIndex = lastWrapCharIndex - 1;
nextCharIndex = currentIndex = lastWrapCharIndex + 1;
}
nextCharIndex = currentIndex = lastWrapCharIndex + 1; // Skip whitespaces
else
{
tmpLine.LastCharIndex = lastWrapCharIndex - 1;
nextCharIndex = currentIndex = lastWrapCharIndex;
}
}
}
else if (layout.TextWrapping == TextWrapping::WrapChars)
@@ -280,7 +275,8 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
break;
}
if (characterEntries != nullptr)
// Avoid adding same character entries again if we skipped characters earlier
if (characterEntries != nullptr && characterEntries->Count() == currentIndex - newlinesCount)
characterEntries->Add(characterCache);
}
@@ -342,7 +338,7 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
// 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;
rootPos.X += ((layout.Bounds.GetWidth() - line.Size.X) * 0.5f);
}
else if (layout.HorizontalAlignment == TextAlignment::Far)
{
@@ -409,7 +405,7 @@ int32 Font::HitTestText(const StringView& text, const Float2& location, const Te
const bool isWhitespace = StringUtils::IsWhitespace(currentChar);
// Apply kerning
if (!isWhitespace && previous.IsValid)
if (!isWhitespace && previous.IsValid && entry.Font != NULL)
{
x += entry.Font->GetKerning(previous.Character, entry.Character);
}

View File

@@ -87,40 +87,6 @@ struct TIsPODType<TextRange>
enum { Value = true };
};
/// <summary>
/// The font line info generated during text processing.
/// </summary>
API_STRUCT(NoDefault) struct FLAXENGINE_API FontLineCache
{
DECLARE_SCRIPTING_TYPE_MINIMAL(FontLineCache);
/// <summary>
/// The root position of the line (upper left corner).
/// </summary>
API_FIELD() Float2 Location;
/// <summary>
/// The line bounds (width and height).
/// </summary>
API_FIELD() Float2 Size;
/// <summary>
/// The first character index (from the input text).
/// </summary>
API_FIELD() int32 FirstCharIndex;
/// <summary>
/// The last character index (from the input text), inclusive.
/// </summary>
API_FIELD() int32 LastCharIndex;
};
template<>
struct TIsPODType<FontLineCache>
{
enum { Value = true };
};
// Font glyph metrics:
//
// xmin xmax

View File

@@ -1247,7 +1247,9 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
if (font == nullptr ||
text.Length() < 0 ||
(customMaterial && (!customMaterial->IsReady() || !customMaterial->IsGUI())))
{
return;
}
// Temporary data
uint32 fontAtlasIndex = 0;
@@ -1362,7 +1364,9 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
text.IsEmpty() ||
layout.Scale <= ZeroTolerance ||
(customMaterial && (!customMaterial->IsReady() || !customMaterial->IsGUI())))
{
return;
}
// Temporary data
uint32 fontAtlasIndex = 0;
@@ -1370,7 +1374,6 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
Float2 invAtlasSize = Float2::One;
float scale = layout.Scale / FontManager::FontScale;
const bool enableFallbackFonts = EnumHasAllFlags(Features, RenderingFeatures::FallbackFonts);
float fontHeightOffset = Math::Ceil((font->GetHeight() + font->GetDescender()) * scale);
RotatedRectangle mask = ClipLayersStack.Peek().Mask;
Float2 customData = { 0.0f, (float)Render2D::Features };
Color colorTint = color * TintLayersStack.Peek();
@@ -1385,6 +1388,15 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
DrawCalls.Resize(drawCallCountBefore + CharacterCache.Count());
Render2DDrawCall* drawCall = &DrawCalls[drawCallCountBefore];
Float2 advanceDirX, advanceDirY;
Matrix3x3::Transform2DVector(Float2(1.0f, 0.0f), TransformCached, advanceDirX);
Matrix3x3::Transform2DVector(Float2(0.0f, 1.0f), TransformCached, advanceDirY);
Float2 scaleVec = (Float2)TransformCached.GetScaleVector() * scale;
Float2 boundsLocation = layout.Bounds.Location * scaleVec / scale;
float fontHeightOffset = (font->GetHeight() + font->GetDescender()) * scaleVec.Y;
advanceDirX *= scale;
advanceDirY *= scale;
// Render all lines
int32 entryIndex = 0;
int32 actualDrawCallsCount = 0;
@@ -1393,9 +1405,7 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
const FontLineCache& line = Lines[lineIndex];
Float2 pointer;
ApplyTransform(line.Location, pointer);
Float2 advanceDirX, advanceDirY;
Matrix3x3::Transform2DVector(Float2(1.0f, 0.0f), TransformCached, advanceDirX);
Matrix3x3::Transform2DVector(Float2(0.0f, 1.0f), TransformCached, advanceDirY);
pointer.Y += fontHeightOffset;
// Render all characters from the line
for (int32 charIndex = line.FirstCharIndex; charIndex < line.LastCharIndex; charIndex++)
@@ -1404,7 +1414,7 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
const FontLineCharacterCache& characterCache = CharacterCache[entryIndex];
const FontCharacterEntry& entry = characterCache.Entry;
pointer += advanceDirX * (characterCache.Kerning * scale);
pointer += advanceDirX * (float)characterCache.Kerning;
// Omit whitespace characters
if (!characterCache.IsWhitespace)
@@ -1426,11 +1436,8 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
// Calculate character size and atlas coordinates
// FIXME: skewed, use advanceDirY for rightBottom
Float2 upperLeft(pointer.X + entry.OffsetX * scale, pointer.Y - entry.OffsetY * scale + fontHeightOffset);
Float2 rightBottom(upperLeft.X + (entry.UVSize.X * scale), upperLeft.Y + (entry.UVSize.Y * scale));
upperLeft += layout.Bounds.Location;
rightBottom += layout.Bounds.Location;
Float2 upperLeft(pointer.X + boundsLocation.X + (entry.OffsetX * scaleVec.X), pointer.Y + boundsLocation.Y - (entry.OffsetY * scaleVec.Y));
Float2 rightBottom(upperLeft.X + (entry.UVSize.X * scaleVec.X), upperLeft.Y + (entry.UVSize.Y * scaleVec.Y));
Float2 upperLeftUV = entry.UV * invAtlasSize;
Float2 rightBottomUV = (entry.UV + entry.UVSize) * invAtlasSize;
@@ -1471,7 +1478,7 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
}
// Move
pointer += advanceDirX * (entry.AdvanceX * scale);
pointer += advanceDirX * (float)entry.AdvanceX;
entryIndex++;
}
}