You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
665 lines
20 KiB
665 lines
20 KiB
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//===========================================================================//
|
|
|
|
#include "gametext.h"
|
|
#include "vgui/ilocalize.h"
|
|
#include "vgui/vgui.h"
|
|
#include <ctype.h>
|
|
#include "gameuisystemsurface.h"
|
|
#include "gameuisystemmgr.h"
|
|
#include "gameuischeme.h"
|
|
#include "graphicgroup.h"
|
|
#include "gameuidefinition.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
// Class factory for scripting.
|
|
class CGameTextClassFactory : IGameUIGraphicClassFactory
|
|
{
|
|
public:
|
|
|
|
CGameTextClassFactory()
|
|
{
|
|
Assert( g_pGameUISystemMgrImpl );
|
|
g_pGameUISystemMgrImpl->RegisterGraphicClassFactory( "text", this );
|
|
}
|
|
|
|
// Returns an instance of a graphic interface (keyvalues owned by caller)
|
|
virtual CGameGraphic *CreateNewGraphicClass( KeyValues *kvRequest, CGameUIDefinition *pMenu )
|
|
{
|
|
Assert( pMenu );
|
|
CGameText *pNewGraphic = NULL;
|
|
|
|
const char *pName = kvRequest->GetString( "name", NULL );
|
|
if ( pName )
|
|
{
|
|
pNewGraphic = new CGameText( pName );
|
|
pMenu->AddGraphicToLayer( pNewGraphic, SUBLAYER_FONT );
|
|
|
|
// Now set the attributes.
|
|
for ( KeyValues *arg = kvRequest->GetFirstSubKey(); arg != NULL; arg = arg->GetNextKey() )
|
|
{
|
|
pNewGraphic->HandleScriptCommand( arg );
|
|
}
|
|
}
|
|
return pNewGraphic;
|
|
}
|
|
};
|
|
static CGameTextClassFactory g_CGameTextClassFactory;
|
|
|
|
|
|
BEGIN_DMXELEMENT_UNPACK ( CGameText )
|
|
DMXELEMENT_UNPACK_FIELD_UTLSTRING( "name", "", m_pName )
|
|
DMXELEMENT_UNPACK_FIELD( "center", "0 0", Vector2D, m_Geometry.m_Center )
|
|
DMXELEMENT_UNPACK_FIELD( "scale", "1 1", Vector2D, m_Geometry.m_Scale )
|
|
DMXELEMENT_UNPACK_FIELD( "rotation", "0", float, m_Geometry.m_Rotation )
|
|
DMXELEMENT_UNPACK_FIELD( "maintainaspectratio", "0", bool, m_Geometry.m_bMaintainAspectRatio )
|
|
DMXELEMENT_UNPACK_FIELD( "sublayertype", "0", int, m_Geometry.m_Sublayer )
|
|
DMXELEMENT_UNPACK_FIELD( "visible", "1", bool, m_Geometry.m_bVisible )
|
|
DMXELEMENT_UNPACK_FIELD( "initialstate", "-1", int, m_CurrentState )
|
|
|
|
DMXELEMENT_UNPACK_FIELD_UTLSTRING( "unlocalizedtext", "NONE", m_CharText )
|
|
DMXELEMENT_UNPACK_FIELD( "allcaps", "0", bool, m_bAllCaps )
|
|
DMXELEMENT_UNPACK_FIELD_UTLSTRING( "fontname", "Default", m_FontName )
|
|
DMXELEMENT_UNPACK_FIELD( "justfication", "0", int, m_Justification )
|
|
DMXELEMENT_UNPACK_FIELD( "color", "255 255 255 255", Color, m_Geometry.m_Color )
|
|
DMXELEMENT_UNPACK_FIELD( "topcolor", "255 255 255 255", Color, m_Geometry.m_TopColor )
|
|
DMXELEMENT_UNPACK_FIELD( "bottomcolor", "255 255 255 255", Color, m_Geometry.m_BottomColor )
|
|
DMXELEMENT_UNPACK_FIELD( "horizgradient", "0", bool, m_Geometry.m_bHorizontalGradient )
|
|
|
|
// color is gotten from log.
|
|
|
|
END_DMXELEMENT_UNPACK( CGameText, s_GameTextUnpack )
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Constructor
|
|
//-----------------------------------------------------------------------------
|
|
CGameText::CGameText( const char *pName )
|
|
{
|
|
m_UnicodeText = NULL;
|
|
m_TextBufferLen = 0;
|
|
m_UnlocalizedTextSymbol = vgui::INVALID_STRING_INDEX;
|
|
m_Font = vgui::INVALID_FONT;
|
|
m_bCanAcceptInput = false;
|
|
|
|
// DME default values.
|
|
m_pName = pName;
|
|
m_Geometry.m_Center.x = 0;
|
|
m_Geometry.m_Center.y = 0;
|
|
m_Geometry.m_Scale.x = 1;
|
|
m_Geometry.m_Scale.y = 1;
|
|
m_Geometry.m_Rotation = 0;
|
|
m_Geometry.m_bMaintainAspectRatio = 1;
|
|
m_Geometry.m_Sublayer = 0;
|
|
m_Geometry.m_bVisible = true;
|
|
m_CurrentState = -1;
|
|
m_CharText = "NONE";
|
|
m_bAllCaps = false;
|
|
m_FontName = "Default";
|
|
m_Justification = JUSTIFICATION_LEFT;
|
|
m_Geometry.m_Color.r = 255;
|
|
m_Geometry.m_Color.g = 255;
|
|
m_Geometry.m_Color.b = 255;
|
|
m_Geometry.m_Color.a = 255;
|
|
m_Geometry.m_TopColor.r = 255;
|
|
m_Geometry.m_TopColor.g = 255;
|
|
m_Geometry.m_TopColor.b = 255;
|
|
m_Geometry.m_TopColor.a = 255;
|
|
m_Geometry.m_BottomColor.r = 255;
|
|
m_Geometry.m_BottomColor.g = 255;
|
|
m_Geometry.m_BottomColor.b = 255;
|
|
m_Geometry.m_BottomColor.a = 255;
|
|
m_Geometry.m_bHorizontalGradient = false;
|
|
|
|
SetText( m_CharText );
|
|
SetFont( m_FontName );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
CGameText::~CGameText()
|
|
{
|
|
if ( m_UnicodeText )
|
|
{
|
|
delete[] m_UnicodeText;
|
|
m_UnicodeText = NULL;
|
|
}
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Create game text using dme elements
|
|
//-----------------------------------------------------------------------------
|
|
bool CGameText::Unserialize( CDmxElement *pGraphic )
|
|
{
|
|
pGraphic->UnpackIntoStructure( this, s_GameTextUnpack );
|
|
|
|
// GEOMETRY
|
|
// Geometry for text is generated. This is because you don't know it until you know the localized text.
|
|
|
|
// ANIMSTATES
|
|
CDmxAttribute *pImageAnims = pGraphic->GetAttribute( "imageanims" );
|
|
if ( !pImageAnims || pImageAnims->GetType() != AT_ELEMENT_ARRAY )
|
|
{
|
|
return false;
|
|
}
|
|
const CUtlVector< CDmxElement * > &imageanims = pImageAnims->GetArray< CDmxElement * >( );
|
|
int nCount = imageanims.Count();
|
|
for ( int i = 0; i < nCount; ++i )
|
|
{
|
|
CAnimData *pAnimData = new CAnimData;
|
|
if ( !pAnimData->Unserialize( imageanims[i] ) )
|
|
{
|
|
delete pAnimData;
|
|
return false;
|
|
}
|
|
m_Anims.AddToTail( pAnimData );
|
|
|
|
}
|
|
|
|
SetText( m_CharText );
|
|
SetFont( m_FontName );
|
|
|
|
SetState( "default" );
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// The attributes that can be modified by scripting are a subset of the DME ones.
|
|
//-----------------------------------------------------------------------------
|
|
KeyValues *CGameText::HandleScriptCommand( KeyValues *args )
|
|
{
|
|
char const *szCommand = args->GetName();
|
|
|
|
if ( !Q_stricmp( "SetText", szCommand ) )
|
|
{
|
|
const char *text = args->GetString( "text" );
|
|
SetText( text );
|
|
return NULL;
|
|
}
|
|
else if ( !Q_stricmp( "SetAllCaps", szCommand ) )
|
|
{
|
|
m_bAllCaps = args->GetBool( "allcaps", false );
|
|
return NULL;
|
|
}
|
|
else if ( !Q_stricmp( "SetFont", szCommand ) )
|
|
{
|
|
SetFont( args->GetString( "fontname" ) );
|
|
return NULL;
|
|
}
|
|
else if ( !Q_stricmp( "SetJustification", szCommand ) )
|
|
{
|
|
// FIXME
|
|
m_Justification = args->GetInt( "justfication", 0 );
|
|
return NULL;
|
|
}
|
|
else if ( !Q_stricmp( "SetTopColor", szCommand ) )
|
|
{
|
|
Color c = args->GetColor( "color", Color( 255, 255, 255, 255 ) );
|
|
m_Geometry.m_TopColor.r = c[0];
|
|
m_Geometry.m_TopColor.g = c[1];
|
|
m_Geometry.m_TopColor.b = c[2];
|
|
m_Geometry.m_TopColor.a = c[3];
|
|
return NULL;
|
|
}
|
|
else if ( !Q_stricmp( "SetBottomColor", szCommand ) )
|
|
{
|
|
Color c = args->GetColor( "color", Color( 255, 255, 255, 255 ) );
|
|
m_Geometry.m_BottomColor.r = c[0];
|
|
m_Geometry.m_BottomColor.g = c[1];
|
|
m_Geometry.m_BottomColor.b = c[2];
|
|
m_Geometry.m_BottomColor.a = c[3];
|
|
return NULL;
|
|
}
|
|
|
|
|
|
else if ( !Q_stricmp( "GetFont", szCommand ) )
|
|
{
|
|
return new KeyValues( "", "font", m_FontName.Get() );
|
|
}
|
|
|
|
return CGameGraphic::HandleScriptCommand( args );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::SetFont( const char *pFontName )
|
|
{
|
|
m_FontName = pFontName;
|
|
if ( m_FontName.Length() )
|
|
{
|
|
m_Font = g_pGameUISystemMgrImpl->GetCurrentScheme()->GetFont( m_FontName, true );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::SetFont( FontHandle_t font )
|
|
{
|
|
m_Font = font;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
FontHandle_t CGameText::GetFont()
|
|
{
|
|
return m_Font;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::SetJustification( Justification_e justify )
|
|
{
|
|
m_Justification = justify;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: takes the string and looks it up in the localization file to convert it to unicode
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::SetText( const char *text )
|
|
{
|
|
if ( !text )
|
|
{
|
|
text = "";
|
|
}
|
|
|
|
// check for localization
|
|
if ( *text == '#' )
|
|
{
|
|
// try lookup in localization tables
|
|
m_UnlocalizedTextSymbol = g_pVGuiLocalize->FindIndex( text + 1 );
|
|
|
|
if ( m_UnlocalizedTextSymbol != vgui::INVALID_STRING_INDEX )
|
|
{
|
|
wchar_t *unicode = g_pVGuiLocalize->GetValueByIndex( m_UnlocalizedTextSymbol );
|
|
SetText(unicode);
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
// convert the ansi string to unicode and use that
|
|
wchar_t unicode[1024];
|
|
g_pVGuiLocalize->ConvertANSIToUnicode( text, unicode, sizeof(unicode) );
|
|
SetText( unicode );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: sets unicode text directly
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::SetText( const wchar_t *unicode, bool bClearUnlocalizedSymbol )
|
|
{
|
|
if ( bClearUnlocalizedSymbol )
|
|
{
|
|
// Clear out unlocalized text symbol so that changing dialog variables
|
|
// doesn't stomp over the custom unicode string we're being set to.
|
|
m_UnlocalizedTextSymbol = vgui::INVALID_STRING_INDEX;
|
|
}
|
|
|
|
if (!unicode)
|
|
{
|
|
unicode = L"";
|
|
}
|
|
|
|
// reallocate the buffer if necessary
|
|
short textLen = (short)wcslen( unicode );
|
|
if ( textLen >= m_TextBufferLen )
|
|
{
|
|
if ( m_UnicodeText )
|
|
{
|
|
delete [] m_UnicodeText;
|
|
m_UnicodeText = NULL;
|
|
}
|
|
m_TextBufferLen = (short)( textLen + 1 );
|
|
m_UnicodeText = new wchar_t[ m_TextBufferLen ];
|
|
}
|
|
|
|
// store the text as unicode
|
|
wcscpy( m_UnicodeText, unicode );
|
|
SetupVertexColors();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::UpdateGeometry()
|
|
{
|
|
if ( m_CurrentState == -1 )
|
|
return;
|
|
|
|
Assert( m_CurrentState < m_Anims.Count() );
|
|
|
|
DmeTime_t flAnimTime = GetAnimationTimePassed();
|
|
|
|
// Update color
|
|
m_Anims[ m_CurrentState ]->m_ColorAnim.GetValue( flAnimTime, &m_Geometry.m_Color );
|
|
|
|
// Update center location
|
|
m_Anims[ m_CurrentState ]->m_CenterPosAnim.GetValue( flAnimTime, &m_Geometry.m_Center );
|
|
|
|
// Update scale
|
|
m_Anims[ m_CurrentState ]->m_ScaleAnim.GetValue( flAnimTime, &m_Geometry.m_Scale );
|
|
|
|
// Update rotation
|
|
m_Anims[ m_CurrentState ]->m_RotationAnim.GetValue( flAnimTime, &m_Geometry.m_Rotation );
|
|
|
|
// Update rotation
|
|
m_Anims[ m_CurrentState ]->m_FontAnim.GetValue( flAnimTime, &m_FontName );
|
|
SetFont( m_FontName );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Rendering helper
|
|
// For text rendering the starting position is top left
|
|
// Center text according to justification.
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::GetStartingTextPosition( int &x, int &y )
|
|
{
|
|
x = 0;
|
|
y = -GetTextRenderHeight()/2;
|
|
|
|
switch ( m_Justification )
|
|
{
|
|
case JUSTIFICATION_LEFT:
|
|
break;
|
|
case JUSTIFICATION_CENTER:
|
|
x = -GetTextRenderWidth()/2;
|
|
break;
|
|
case JUSTIFICATION_RIGHT:
|
|
x = -GetTextRenderWidth();
|
|
break;
|
|
default:
|
|
Assert(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Rendering helper
|
|
// Determine what list to put this quad into, and make an entry slot for it.
|
|
//-----------------------------------------------------------------------------
|
|
CRenderGeometry *CGameText::GetGeometryEntry( CUtlVector< RenderGeometryList_t > &renderGeometryLists, int firstListIndex, int fontTextureID )
|
|
{
|
|
CRenderGeometry *pRenderGeometry = NULL;
|
|
if ( renderGeometryLists[firstListIndex].Count() != 0 )
|
|
{
|
|
for ( int j = firstListIndex; j < renderGeometryLists.Count(); ++j )
|
|
{
|
|
if ( fontTextureID == renderGeometryLists[j][0].m_FontTextureID )
|
|
{
|
|
int index = renderGeometryLists[j].AddToTail();
|
|
pRenderGeometry = &renderGeometryLists[j][index];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Didn't find a match for this textureID, time to make a new list of quads for this texture.
|
|
if ( pRenderGeometry == NULL )
|
|
{
|
|
int newListIndex;
|
|
if ( renderGeometryLists[firstListIndex].Count() == 0 ) // This is the first quad we are adding to this font layer.
|
|
{
|
|
newListIndex = firstListIndex;
|
|
}
|
|
else
|
|
{
|
|
newListIndex = renderGeometryLists.AddToTail();
|
|
}
|
|
int index = renderGeometryLists[newListIndex].AddToTail();
|
|
pRenderGeometry = &renderGeometryLists[newListIndex][index];
|
|
}
|
|
|
|
return pRenderGeometry;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::SetupVertexColors()
|
|
{
|
|
// There is no text to generate if these are not set.
|
|
if ( !m_UnicodeText )
|
|
return;
|
|
|
|
m_Geometry.m_VertexColors.RemoveAll();
|
|
|
|
color32 c;
|
|
c.r = 255;
|
|
c.g = 255;
|
|
c.b = 255;
|
|
c.a = 255;
|
|
|
|
for ( wchar_t *wsz = m_UnicodeText; *wsz != 0; wsz++ )
|
|
{
|
|
// Create 4 vertex colors per letter.
|
|
m_Geometry.m_VertexColors.AddToTail( c );
|
|
m_Geometry.m_VertexColors.AddToTail( c );
|
|
m_Geometry.m_VertexColors.AddToTail( c );
|
|
m_Geometry.m_VertexColors.AddToTail( c );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::UpdateRenderData( color32 parentColor, CUtlVector< RenderGeometryList_t > &renderGeometryLists, int firstListIndex )
|
|
{
|
|
if ( !m_Geometry.m_bVisible )
|
|
return;
|
|
|
|
// There is no text to generate if these are not set.
|
|
if ( !m_UnicodeText )
|
|
return;
|
|
|
|
if ( m_Font == vgui::INVALID_FONT)
|
|
return;
|
|
|
|
m_Geometry.SetResultantColor( parentColor );
|
|
|
|
int x, y;
|
|
GetStartingTextPosition( x, y );
|
|
|
|
FontCharRenderInfo info;
|
|
info.currentFont = m_Font;
|
|
info.drawType = FONT_DRAW_DEFAULT;
|
|
|
|
int letterIndex = 0;
|
|
m_Geometry.m_RelativePositions.RemoveAll();
|
|
for ( wchar_t *wsz = m_UnicodeText; *wsz != 0; wsz++, letterIndex += 4 )
|
|
{
|
|
Assert( letterIndex < m_Geometry.m_VertexColors.Count() );
|
|
// Update FontCharRenderInfo
|
|
info.x = x;
|
|
info.y = y;
|
|
info.ch = wsz[0];
|
|
if ( m_bAllCaps )
|
|
{
|
|
info.ch = towupper( info.ch );
|
|
}
|
|
|
|
Vector2D relPositions[4];
|
|
g_pGameUISystemSurface->GetUnicodeCharRenderPositions( info, relPositions );
|
|
|
|
// get the character texture from the cache and the char's texture coords.
|
|
float *texCoords = NULL; // note this returns the static from the fonttexturecache... FIXME?
|
|
g_pGameUISystemSurface->GetTextureForChar( info, &texCoords );
|
|
|
|
x += g_pGameUISystemSurface->GetCharacterWidth( m_Font, info.ch );
|
|
|
|
// Get a geometry from the correct texture list.
|
|
CRenderGeometry *pRenderGeometry = GetGeometryEntry( renderGeometryLists, firstListIndex, info.textureId );
|
|
Assert( pRenderGeometry != NULL );
|
|
|
|
// Populate the new entry.
|
|
pRenderGeometry->m_FontTextureID = info.textureId;
|
|
Vector screenPosition;
|
|
Vector relativePosition;
|
|
|
|
// Top left
|
|
relativePosition.Init( relPositions[0].x, relPositions[0].y, 0 );
|
|
m_Geometry.m_RelativePositions.AddToTail( Vector2D( relPositions[0].x, relPositions[0].y ) );
|
|
VectorTransform( relativePosition, m_Geometry.m_RenderToScreen, screenPosition );
|
|
pRenderGeometry->m_Positions.AddToTail( Vector2D( floor( screenPosition.x ), floor( screenPosition.y ) ) );
|
|
pRenderGeometry->m_VertexColors.AddToTail( m_Geometry.m_VertexColors[letterIndex] );
|
|
pRenderGeometry->m_TextureCoords.AddToTail( Vector2D( texCoords[0], texCoords[1] ) );
|
|
|
|
// Top right
|
|
relativePosition.Init( relPositions[1].x, relPositions[1].y, 0 );
|
|
m_Geometry.m_RelativePositions.AddToTail( Vector2D( relPositions[1].x, relPositions[1].y ) );
|
|
VectorTransform( relativePosition, m_Geometry.m_RenderToScreen, screenPosition );
|
|
pRenderGeometry->m_Positions.AddToTail( Vector2D( floor( screenPosition.x ), floor( screenPosition.y ) ) );
|
|
pRenderGeometry->m_VertexColors.AddToTail( m_Geometry.m_VertexColors[letterIndex + 1] );
|
|
pRenderGeometry->m_TextureCoords.AddToTail( Vector2D( texCoords[2], texCoords[1] ) );
|
|
|
|
// Bottom right
|
|
relativePosition.Init( relPositions[2].x, relPositions[2].y, 0 );
|
|
m_Geometry.m_RelativePositions.AddToTail( Vector2D( relPositions[2].x, relPositions[2].y ) );
|
|
VectorTransform( relativePosition, m_Geometry.m_RenderToScreen, screenPosition );
|
|
pRenderGeometry->m_Positions.AddToTail( Vector2D( floor( screenPosition.x ), floor( screenPosition.y ) ) );
|
|
pRenderGeometry->m_VertexColors.AddToTail( m_Geometry.m_VertexColors[letterIndex + 2] );
|
|
pRenderGeometry->m_TextureCoords.AddToTail( Vector2D( texCoords[2], texCoords[3] ) );
|
|
|
|
// Bottom left
|
|
relativePosition.Init( relPositions[3].x, relPositions[3].y, 0 );
|
|
m_Geometry.m_RelativePositions.AddToTail( Vector2D( relPositions[3].x, relPositions[3].y ) );
|
|
VectorTransform( relativePosition, m_Geometry.m_RenderToScreen, screenPosition );
|
|
pRenderGeometry->m_Positions.AddToTail( Vector2D( floor( screenPosition.x ), floor( screenPosition.y ) ) );
|
|
pRenderGeometry->m_VertexColors.AddToTail( m_Geometry.m_VertexColors[letterIndex + 3] );
|
|
pRenderGeometry->m_TextureCoords.AddToTail( Vector2D( texCoords[0], texCoords[3] ) );
|
|
|
|
pRenderGeometry->m_AnimationRate = m_Geometry.m_AnimationRate;
|
|
pRenderGeometry->m_AnimStartTime = m_Geometry.m_AnimStartTime;
|
|
pRenderGeometry->m_bAnimate = m_Geometry.m_bAnimate;
|
|
pRenderGeometry->m_pImageAlias = NULL;
|
|
}
|
|
|
|
|
|
m_Geometry.CalculateExtents();
|
|
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Have to do this separately because extents are drawn as rects.
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::DrawExtents( CUtlVector< RenderGeometryList_t > &renderGeometryLists, int firstListIndex )
|
|
{
|
|
color32 extentLineColor = { 0, 25, 255, 255 };
|
|
m_Geometry.DrawExtents( renderGeometryLists, firstListIndex, extentLineColor );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Get the size of a text string in pixels
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::GetTextSize( int &wide, int &tall )
|
|
{
|
|
wide = 0;
|
|
tall = 0;
|
|
|
|
if ( m_Font == vgui::INVALID_FONT )
|
|
return;
|
|
|
|
// For height, use the remapped font
|
|
tall = GetTextRenderHeight();
|
|
wide = GetTextRenderWidth();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Return height of text in pixels
|
|
//-----------------------------------------------------------------------------
|
|
int CGameText::GetTextRenderWidth()
|
|
{
|
|
int wordWidth = 0;
|
|
int textLen = wcslen( m_UnicodeText );
|
|
for ( int i = 0; i < textLen; i++ )
|
|
{
|
|
wchar_t ch = m_UnicodeText[ i ];
|
|
|
|
if ( m_bAllCaps )
|
|
{
|
|
ch = towupper( ch );
|
|
}
|
|
|
|
// handle stupid special characters, these should be removed
|
|
if ( ch == '&' && m_UnicodeText[ i + 1 ] != 0 )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
wordWidth += g_pGameUISystemSurface->GetCharacterWidth( m_Font, ch );
|
|
}
|
|
|
|
return wordWidth;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Return width of text in pixels
|
|
//-----------------------------------------------------------------------------
|
|
int CGameText::GetTextRenderHeight()
|
|
{
|
|
return g_pGameUISystemSurface->GetFontTall( m_Font );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Note corner colors will be stomped if the base graphic's color changes.
|
|
//-----------------------------------------------------------------------------
|
|
void CGameText::SetColor( color32 c )
|
|
{
|
|
m_Geometry.m_TopColor = c;
|
|
m_Geometry.m_BottomColor = c;
|
|
// Remove first to force the new colors in.
|
|
m_Geometry.m_VertexColors.RemoveAll();
|
|
SetupVertexColors();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Determine if x,y is inside the graphic.
|
|
//-----------------------------------------------------------------------------
|
|
bool CGameText::HitTest( int x, int y )
|
|
{
|
|
if ( !m_Geometry.m_bVisible )
|
|
return false;
|
|
|
|
// Just using extents for now, note extents don't take into account rotation.
|
|
Vector2D point0( m_Geometry.m_Extents.m_TopLeft.x, m_Geometry.m_Extents.m_TopLeft.y );
|
|
Vector2D point1( m_Geometry.m_Extents.m_BottomRight.x, m_Geometry.m_Extents.m_TopLeft.y );
|
|
Vector2D point2( m_Geometry.m_Extents.m_BottomRight.x, m_Geometry.m_Extents.m_BottomRight.y );
|
|
Vector2D point3( m_Geometry.m_Extents.m_TopLeft.x, m_Geometry.m_Extents.m_BottomRight.y );
|
|
if ( PointTriangleHitTest( point0, point1, point2, Vector2D( x, y ) ) )
|
|
{
|
|
//Msg( "%d, %d hit\n", x, y );
|
|
return true;
|
|
}
|
|
if ( PointTriangleHitTest( point0, point2, point3, Vector2D( x, y ) ) )
|
|
{
|
|
//Msg( "%d, %d hit\n", x, y );
|
|
return true;
|
|
}
|
|
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
|