Add multiline spacing and GetTextSize to Atom Font

This commit is contained in:
nvsickle
2021-05-11 12:18:04 -07:00
parent 64d53d1fab
commit 7ff5c0e105
4 changed files with 83 additions and 32 deletions
+4
View File
@@ -150,6 +150,7 @@ struct STextDrawContext
Vec2 m_size;
Vec2i m_requestSize;
float m_widthScale;
float m_lineSpacing;
float m_clipX;
float m_clipY;
@@ -180,6 +181,7 @@ struct STextDrawContext
, m_size(16.0f, 16.0f)
, m_requestSize(static_cast<int32>(m_size.x), static_cast<int32>(m_size.y))
, m_widthScale(1.0f)
, m_lineSpacing(0.f)
, m_clipX(0)
, m_clipY(0)
, m_clipWidth(0)
@@ -214,11 +216,13 @@ struct STextDrawContext
void SetTransform(const Matrix34& transform) { m_transform = transform; }
void SetBaseState(int baseState) { m_baseState = baseState; }
void SetOverrideViewProjMatrices(bool overrideViewProjMatrices) { m_overrideViewProjMatrices = overrideViewProjMatrices; }
void SetLineSpacing(float lineSpacing) { m_lineSpacing = lineSpacing; }
float GetCharWidth() const { return m_size.x; }
float GetCharHeight() const { return m_size.y; }
float GetCharWidthScale() const { return m_widthScale; }
int GetFlags() const { return m_drawTextFlags; }
float GetLineSpacing() const { return m_lineSpacing; }
bool IsColorOverridden() const { return m_colorOverride.a != 0; }
};
@@ -44,6 +44,7 @@ namespace AzFramework
AZ::Vector3 m_position; //! world space position for 3d draws, screen space x,y,depth for 2d.
AZ::Color m_color = AZ::Colors::White; //! Color to draw the text
AZ::Vector2 m_scale = AZ::Vector2(1.0f); //! font scale
float m_lineSpacing; //! Spacing between new lines, as a percentage of m_scale.
TextHorizontalAlignment m_hAlign = TextHorizontalAlignment::Left; //! Horizontal text alignment
TextVerticalAlignment m_vAlign = TextVerticalAlignment::Top; //! Vertical text alignment
bool m_monospace = false; //! disable character proportional spacing
@@ -67,6 +68,9 @@ namespace AzFramework
virtual void DrawScreenAlignedText3d(
const TextDrawParameters& params,
const AZStd::string_view& string) = 0;
virtual AZ::Vector2 GetTextSize(
const TextDrawParameters& params,
const AZStd::string_view& string) = 0;
};
class FontQueryInterface
@@ -213,6 +213,10 @@ namespace AZ
const AzFramework::TextDrawParameters& params,
const AZStd::string_view& string) override;
AZ::Vector2 GetTextSize(
const AzFramework::TextDrawParameters& params,
const AZStd::string_view& string) override;
public:
FFont(AtomFont* atomFont, const char* fontName);
@@ -282,6 +286,16 @@ namespace AZ
RPI::WindowContextSharedPtr GetDefaultWindowContext() const;
RPI::ViewportContextPtr GetDefaultViewportContext() const;
struct DrawParameters
{
TextDrawContext m_ctx;
AZ::Vector2 m_position;
AZ::Vector2 m_size;
AZ::RPI::ViewportContext* m_viewportContext;
const AZ::RHI::Viewport* m_viewport;
};
DrawParameters ExtractDrawParameters(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string, bool forceCalculateSize);
private:
static constexpr uint32_t NumBuffers = 2;
static constexpr float WindowScaleWidth = 800.0f;
@@ -505,7 +505,7 @@ Vec2 AZ::FFont::GetTextSizeUInternal(
}
charX = offset.x;
charY += size.y;
charY += size.y * (1.f + ctx.GetLineSpacing());
if (charY > maxH)
{
@@ -944,7 +944,7 @@ int AZ::FFont::CreateQuadsForText(const RHI::Viewport& viewport, float x, float
case '\n':
{
charX = baseXY.x + offset.x;
charY += size.y;
charY += size.y * (1.f + ctx.GetLineSpacing());
continue;
}
break;
@@ -1674,47 +1674,47 @@ static void SetCommonContextFlags(AZ::TextDrawContext& ctx, const AzFramework::T
}
}
void AZ::FFont::DrawScreenAlignedText2d(
const AzFramework::TextDrawParameters& params,
const AZStd::string_view& string)
AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string, bool forceCalculateSize)
{
DrawParameters internalParams;
if (params.m_drawViewportId == AzFramework::InvalidViewportId ||
string.empty())
{
return;
return internalParams;
}
//Code mostly duplicated from CRenderer::Draw2dTextWithDepth
float posX = params.m_position.GetX();
float posY = params.m_position.GetY();
AZ::RPI::ViewportContext* viewportContext = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()->GetViewportContextById(params.m_drawViewportId).get();
const AZ::RHI::Viewport& viewport = viewportContext->GetWindowContext()->GetViewport();
internalParams.m_viewportContext = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()->GetViewportContextById(params.m_drawViewportId).get();
const AZ::RHI::Viewport& viewport = internalParams.m_viewportContext->GetWindowContext()->GetViewport();
internalParams.m_viewport = &viewport;
if (params.m_virtual800x600ScreenSize)
{
posX *= WindowScaleWidth / (viewport.m_maxX - viewport.m_minX);
posY *= WindowScaleHeight / (viewport.m_maxY - viewport.m_minY);
}
TextDrawContext ctx;
ctx.SetBaseState(GS_NODEPTHTEST);
ctx.SetColor(AZColorToLYColorF(params.m_color));
ctx.SetCharWidthScale((params.m_monospace || params.m_scaleWithWindow) ? 0.5f : 1.0f);
ctx.EnableFrame(false);
ctx.SetProportional(!params.m_monospace && params.m_scaleWithWindow);
ctx.SetSizeIn800x600(params.m_scaleWithWindow && params.m_virtual800x600ScreenSize);
ctx.SetSize(AZVec2ToLYVec2(UiDraw_TextSizeFactor * params.m_scale));
internalParams.m_ctx.SetBaseState(GS_NODEPTHTEST);
internalParams.m_ctx.SetColor(AZColorToLYColorF(params.m_color));
internalParams.m_ctx.SetCharWidthScale((params.m_monospace || params.m_scaleWithWindow) ? 0.5f : 1.0f);
internalParams.m_ctx.EnableFrame(false);
internalParams.m_ctx.SetProportional(!params.m_monospace && params.m_scaleWithWindow);
internalParams.m_ctx.SetSizeIn800x600(params.m_scaleWithWindow && params.m_virtual800x600ScreenSize);
internalParams.m_ctx.SetSize(AZVec2ToLYVec2(UiDraw_TextSizeFactor * params.m_scale));
internalParams.m_ctx.SetLineSpacing(params.m_lineSpacing);
if (params.m_monospace || !params.m_scaleWithWindow)
{
ScaleCoord(viewport, posX, posY);
}
if (params.m_hAlign != AzFramework::TextHorizontalAlignment::Left ||
params.m_vAlign != AzFramework::TextVerticalAlignment::Top)
params.m_vAlign != AzFramework::TextVerticalAlignment::Top ||
forceCalculateSize)
{
Vec2 textSize = GetTextSizeUInternal(viewport, string.data(), params.m_multiline, ctx);
Vec2 textSize = GetTextSizeUInternal(viewport, string.data(), params.m_multiline, internalParams.m_ctx);
// If we're using virtual 800x600 coordinates, convert the text size from
// pixels to that before using it as an offset.
if (ctx.m_sizeIn800x600)
if (internalParams.m_ctx.m_sizeIn800x600)
{
float width = 1.0f;
float height = 1.0f;
@@ -1740,19 +1740,33 @@ void AZ::FFont::DrawScreenAlignedText2d(
{
posY -= textSize.y;
}
internalParams.m_size = AZ::Vector2{textSize.x, textSize.y};
}
SetCommonContextFlags(internalParams.m_ctx, params);
internalParams.m_ctx.m_drawTextFlags |= eDrawText_2D;
internalParams.m_position = AZ::Vector2{posX, posY};
return internalParams;
}
void AZ::FFont::DrawScreenAlignedText2d(
const AzFramework::TextDrawParameters& params,
const AZStd::string_view& string)
{
DrawParameters internalParams = ExtractDrawParameters(params, string, false);
if (!internalParams.m_viewportContext)
{
return;
}
SetCommonContextFlags(ctx, params);
ctx.m_drawTextFlags |= eDrawText_2D;
DrawStringUInternal(
viewport,
viewportContext,
posX,
posY,
*internalParams.m_viewport,
internalParams.m_viewportContext,
internalParams.m_position.GetX(),
internalParams.m_position.GetY(),
params.m_position.GetZ(), // Z
string.data(),
params.m_multiline,
ctx
internalParams.m_ctx
);
}
@@ -1760,13 +1774,12 @@ void AZ::FFont::DrawScreenAlignedText3d(
const AzFramework::TextDrawParameters& params,
const AZStd::string_view& string)
{
if (params.m_drawViewportId == AzFramework::InvalidViewportId ||
string.empty())
DrawParameters internalParams = ExtractDrawParameters(params, string, false);
if (!internalParams.m_viewportContext)
{
return;
}
AZ::RPI::ViewportContext* viewportContext = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()->GetViewportContextById(params.m_drawViewportId).get();
AZ::RPI::ViewPtr currentView = viewportContext->GetDefaultView();
AZ::RPI::ViewPtr currentView = internalParams.m_viewportContext->GetDefaultView();
if (!currentView)
{
return;
@@ -1778,7 +1791,23 @@ void AZ::FFont::DrawScreenAlignedText3d(
);
AzFramework::TextDrawParameters param2d = params;
param2d.m_position = positionNDC;
DrawScreenAlignedText2d(param2d, string);
DrawStringUInternal(
*internalParams.m_viewport,
internalParams.m_viewportContext,
internalParams.m_position.GetX(),
internalParams.m_position.GetY(),
params.m_position.GetZ(), // Z
string.data(),
params.m_multiline,
internalParams.m_ctx
);
}
AZ::Vector2 AZ::FFont::GetTextSize(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string)
{
DrawParameters sizeParams = ExtractDrawParameters(params, string, true);
return sizeParams.m_size;
}
#endif //USE_NULLFONT_ALWAYS