You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
257 lines
8.8 KiB
C++
257 lines
8.8 KiB
C++
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "SlatePrivatePCH.h"
|
|
|
|
#if WITH_FANCY_TEXT
|
|
|
|
#include "SlateTextRun.h"
|
|
|
|
TSharedRef< FSlateTextRun > FSlateTextRun::Create( const FRunInfo& InRunInfo, const TSharedRef< const FString >& InText, const FTextBlockStyle& Style )
|
|
{
|
|
return MakeShareable( new FSlateTextRun( InRunInfo, InText, Style ) );
|
|
}
|
|
|
|
TSharedRef< FSlateTextRun > FSlateTextRun::Create( const FRunInfo& InRunInfo, const TSharedRef< const FString >& InText, const FTextBlockStyle& Style, const FTextRange& InRange )
|
|
{
|
|
return MakeShareable( new FSlateTextRun( InRunInfo, InText, Style, InRange ) );
|
|
}
|
|
|
|
FTextRange FSlateTextRun::GetTextRange() const
|
|
{
|
|
return Range;
|
|
}
|
|
|
|
void FSlateTextRun::SetTextRange( const FTextRange& Value )
|
|
{
|
|
Range = Value;
|
|
}
|
|
|
|
int16 FSlateTextRun::GetBaseLine( float Scale ) const
|
|
{
|
|
const TSharedRef< FSlateFontMeasure > FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
|
|
return FontMeasure->GetBaseline( Style.Font, Scale ) - FMath::Min(0.0f, Style.ShadowOffset.Y * Scale);
|
|
}
|
|
|
|
int16 FSlateTextRun::GetMaxHeight( float Scale ) const
|
|
{
|
|
const TSharedRef< FSlateFontMeasure > FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
|
|
return FontMeasure->GetMaxCharacterHeight( Style.Font, Scale ) + FMath::Abs(Style.ShadowOffset.Y * Scale);
|
|
}
|
|
|
|
FVector2D FSlateTextRun::Measure( int32 BeginIndex, int32 EndIndex, float Scale ) const
|
|
{
|
|
const FVector2D ShadowOffsetToApply((EndIndex == Range.EndIndex) ? FMath::Abs(Style.ShadowOffset.X * Scale) : 0.0f, FMath::Abs(Style.ShadowOffset.Y * Scale));
|
|
|
|
if ( EndIndex - BeginIndex == 0 )
|
|
{
|
|
return FVector2D( ShadowOffsetToApply.X * Scale, GetMaxHeight( Scale ) );
|
|
}
|
|
|
|
const TSharedRef< FSlateFontMeasure > FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
|
|
return FontMeasure->Measure( **Text, BeginIndex, EndIndex, Style.Font, true, Scale ) + ShadowOffsetToApply;
|
|
}
|
|
|
|
int8 FSlateTextRun::GetKerning(int32 CurrentIndex, float Scale) const
|
|
{
|
|
const int32 PreviousIndex = CurrentIndex - 1;
|
|
if ( PreviousIndex < 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
const TSharedRef< FSlateFontMeasure > FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
|
|
return FontMeasure->GetKerning( Style.Font, Scale, (*Text)[ PreviousIndex ], (*Text)[ CurrentIndex ] );
|
|
}
|
|
|
|
TSharedRef< ILayoutBlock > FSlateTextRun::CreateBlock( int32 BeginIndex, int32 EndIndex, FVector2D Size, const TSharedPtr< IRunRenderer >& Renderer )
|
|
{
|
|
return FDefaultLayoutBlock::Create( SharedThis( this ), FTextRange( BeginIndex, EndIndex ), Size, Renderer );
|
|
}
|
|
|
|
int32 FSlateTextRun::OnPaint( const FPaintArgs& Args, const FTextLayout::FLineView& Line, const TSharedRef< ILayoutBlock >& Block, const FTextBlockStyle& DefaultStyle, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const
|
|
{
|
|
const FSlateRect ClippingRect = AllottedGeometry.GetClippingRect().IntersectionWith(MyClippingRect);
|
|
const ESlateDrawEffect::Type DrawEffects = bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect;
|
|
|
|
const bool ShouldDropShadow = Style.ShadowOffset.Size() > 0;
|
|
const FVector2D BlockLocationOffset = Block->GetLocationOffset();
|
|
const FTextRange BlockRange = Block->GetTextRange();
|
|
|
|
// The block size and offset values are pre-scaled, so we need to account for that when converting the block offsets into paint geometry
|
|
const float InverseScale = Inverse(AllottedGeometry.Scale);
|
|
|
|
// A negative shadow offset should be applied as a positive offset to the text to avoid clipping issues
|
|
const FVector2D DrawShadowOffset(
|
|
(Style.ShadowOffset.X > 0.0f) ? Style.ShadowOffset.X * AllottedGeometry.Scale : 0.0f,
|
|
(Style.ShadowOffset.Y > 0.0f) ? Style.ShadowOffset.Y * AllottedGeometry.Scale : 0.0f
|
|
);
|
|
const FVector2D DrawTextOffset(
|
|
(Style.ShadowOffset.X < 0.0f) ? -Style.ShadowOffset.X * AllottedGeometry.Scale : 0.0f,
|
|
(Style.ShadowOffset.Y < 0.0f) ? -Style.ShadowOffset.Y * AllottedGeometry.Scale : 0.0f
|
|
);
|
|
|
|
// Draw the optional shadow
|
|
if ( ShouldDropShadow )
|
|
{
|
|
FSlateDrawElement::MakeText(
|
|
OutDrawElements,
|
|
++LayerId,
|
|
AllottedGeometry.ToPaintGeometry(TransformVector(InverseScale, Block->GetSize()), FSlateLayoutTransform(TransformPoint(InverseScale, Block->GetLocationOffset() + DrawShadowOffset))),
|
|
Text.Get(),
|
|
BlockRange.BeginIndex,
|
|
BlockRange.EndIndex,
|
|
Style.Font,
|
|
ClippingRect,
|
|
DrawEffects,
|
|
InWidgetStyle.GetColorAndOpacityTint() * Style.ShadowColorAndOpacity
|
|
);
|
|
}
|
|
|
|
// Draw the text itself
|
|
FSlateDrawElement::MakeText(
|
|
OutDrawElements,
|
|
++LayerId,
|
|
AllottedGeometry.ToPaintGeometry(TransformVector(InverseScale, Block->GetSize()), FSlateLayoutTransform(TransformPoint(InverseScale, Block->GetLocationOffset() + DrawTextOffset))),
|
|
Text.Get(),
|
|
BlockRange.BeginIndex,
|
|
BlockRange.EndIndex,
|
|
Style.Font,
|
|
ClippingRect,
|
|
DrawEffects,
|
|
InWidgetStyle.GetColorAndOpacityTint() * Style.ColorAndOpacity.GetColor(InWidgetStyle)
|
|
);
|
|
|
|
return LayerId;
|
|
}
|
|
|
|
const TArray< TSharedRef<SWidget> >& FSlateTextRun::GetChildren()
|
|
{
|
|
static TArray< TSharedRef<SWidget> > NoChildren;
|
|
return NoChildren;
|
|
}
|
|
|
|
void FSlateTextRun::ArrangeChildren( const TSharedRef< ILayoutBlock >& Block, const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const
|
|
{
|
|
// no widgets
|
|
}
|
|
|
|
int32 FSlateTextRun::GetTextIndexAt( const TSharedRef< ILayoutBlock >& Block, const FVector2D& Location, float Scale, ETextHitPoint* const OutHitPoint ) const
|
|
{
|
|
const FVector2D& BlockOffset = Block->GetLocationOffset();
|
|
const FVector2D& BlockSize = Block->GetSize();
|
|
|
|
const float Left = BlockOffset.X;
|
|
const float Top = BlockOffset.Y;
|
|
const float Right = BlockOffset.X + BlockSize.X;
|
|
const float Bottom = BlockOffset.Y + BlockSize.Y;
|
|
|
|
const bool ContainsPoint = Location.X >= Left && Location.X < Right && Location.Y >= Top && Location.Y < Bottom;
|
|
|
|
if ( !ContainsPoint )
|
|
{
|
|
return INDEX_NONE;
|
|
}
|
|
|
|
const FTextRange BlockRange = Block->GetTextRange();
|
|
const TSharedRef< FSlateFontMeasure > FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
|
|
|
|
const int32 Index = FontMeasure->FindCharacterIndexAtOffset( Text.Get(), BlockRange.BeginIndex, BlockRange.EndIndex, Style.Font, Location.X - BlockOffset.X, true, Scale );
|
|
if (OutHitPoint)
|
|
{
|
|
*OutHitPoint = (Index == BlockRange.EndIndex) ? ETextHitPoint::RightGutter : ETextHitPoint::WithinText;
|
|
}
|
|
|
|
return Index;
|
|
}
|
|
|
|
FVector2D FSlateTextRun::GetLocationAt( const TSharedRef< ILayoutBlock >& Block, int32 Offset, float Scale ) const
|
|
{
|
|
const FVector2D& BlockOffset = Block->GetLocationOffset();
|
|
const FTextRange& BlockRange = Block->GetTextRange();
|
|
|
|
if (BlockRange.BeginIndex + Offset == BlockRange.EndIndex)
|
|
{
|
|
return BlockOffset + Block->GetSize();
|
|
}
|
|
|
|
const TSharedRef< FSlateFontMeasure > FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
|
|
const FVector2D OffsetLocation = FontMeasure->Measure( Text.Get(), BlockRange.BeginIndex, BlockRange.BeginIndex + Offset, Style.Font, true, Scale );
|
|
|
|
return BlockOffset + OffsetLocation;
|
|
}
|
|
|
|
void FSlateTextRun::Move(const TSharedRef<FString>& NewText, const FTextRange& NewRange)
|
|
{
|
|
Text = NewText;
|
|
Range = NewRange;
|
|
|
|
#if TEXT_LAYOUT_DEBUG
|
|
DebugSlice = FString( InRange.EndIndex - InRange.BeginIndex, (**Text) + InRange.BeginIndex );
|
|
#endif
|
|
}
|
|
|
|
TSharedRef<IRun> FSlateTextRun::Clone() const
|
|
{
|
|
return FSlateTextRun::Create(RunInfo, Text, Style, Range);
|
|
}
|
|
|
|
void FSlateTextRun::AppendTextTo(FString& AppendToText) const
|
|
{
|
|
AppendToText.Append(**Text + Range.BeginIndex, Range.Len());
|
|
}
|
|
|
|
void FSlateTextRun::AppendTextTo(FString& AppendToText, const FTextRange& PartialRange) const
|
|
{
|
|
check(Range.BeginIndex <= PartialRange.BeginIndex);
|
|
check(Range.EndIndex >= PartialRange.EndIndex);
|
|
|
|
AppendToText.Append(**Text + PartialRange.BeginIndex, PartialRange.Len());
|
|
}
|
|
|
|
const FRunInfo& FSlateTextRun::GetRunInfo() const
|
|
{
|
|
return RunInfo;
|
|
}
|
|
|
|
ERunAttributes FSlateTextRun::GetRunAttributes() const
|
|
{
|
|
return ERunAttributes::SupportsText;
|
|
}
|
|
|
|
FSlateTextRun::FSlateTextRun( const FRunInfo& InRunInfo, const TSharedRef< const FString >& InText, const FTextBlockStyle& InStyle )
|
|
: RunInfo( InRunInfo )
|
|
, Text( InText )
|
|
, Style( InStyle )
|
|
, Range( 0, Text->Len() )
|
|
#if TEXT_LAYOUT_DEBUG
|
|
, DebugSlice( FString( Text->Len(), **Text ) )
|
|
#endif
|
|
{
|
|
|
|
}
|
|
|
|
FSlateTextRun::FSlateTextRun( const FRunInfo& InRunInfo, const TSharedRef< const FString >& InText, const FTextBlockStyle& InStyle, const FTextRange& InRange )
|
|
: RunInfo( InRunInfo )
|
|
, Text( InText )
|
|
, Style( InStyle )
|
|
, Range( InRange )
|
|
#if TEXT_LAYOUT_DEBUG
|
|
, DebugSlice( FString( InRange.EndIndex - InRange.BeginIndex, (**Text) + InRange.BeginIndex ) )
|
|
#endif
|
|
{
|
|
|
|
}
|
|
|
|
FSlateTextRun::FSlateTextRun( const FSlateTextRun& Run )
|
|
: RunInfo( Run.RunInfo )
|
|
, Text( Run.Text )
|
|
, Style( Run.Style )
|
|
, Range( Run.Range )
|
|
#if TEXT_LAYOUT_DEBUG
|
|
, DebugSlice( Run.DebugSlice )
|
|
#endif
|
|
{
|
|
|
|
}
|
|
|
|
#endif //WITH_FANCY_TEXT
|