Skip to content
Permalink
Browse files

Add dxGetTextSize function (#935)

* Add dxGetTextHeight function

Syntax: float dxGetTextHeight ( string text, [float width, float scaleXY=1.0, float=scaleY=1.0, mixed font="default", bool wordBreak=false, bool colorCoded=false] )

* Change dxGetTextHeight to dxGetTextSize

* Revert unintended line ending changes

* Add dxGetTextSize

Add DxFont:getTextSize()

* Rename GetEndSpacesWidth to GetTrailingSpacesWidth

* Rename GetEndSpacesWidth to GetTrailingSpacesWidth

* Fix trailing space width calculation

* Remove spaces calculation

* Hard error
  • Loading branch information
StrixG committed Mar 14, 2020
1 parent 8b98f79 commit f6be063d4ea0f039f6fd4b256ab106171f1492ff
@@ -644,30 +644,10 @@ float CGraphics::GetDXTextExtent(const char* szText, float fScale, LPD3DXFONT pD
// DT_CALCRECT may not take space characters at the end of a line
// into consideration for the rect size.
// Count the amount of space characters at the end
int iSpaceCount = 0;
for (auto c = strText.rbegin(); c != strText.rend(); ++c)
{
if (*c == ' ')
++iSpaceCount;
else
break;
}

// Compute the size of a single space and use that
// to get the width of the ignored space characters
int iAdditionalPixels = 0;
if (iSpaceCount > 0)
{
HDC dc = pDXFont->GetDC();
SIZE size;
GetTextExtentPoint32W(dc, L" ", 1, &size);
iAdditionalPixels = iSpaceCount * size.cx;
// Remove trailing spaces from the text
strText = strText.Left(strText.length() - iSpaceCount);
}
int iAdditionalPixels = GetTrailingSpacesWidth(pDXFont, strText);

// Compute the size of the text itself
pDXFont->DrawTextW(NULL, strText.c_str(), strText.length(), &rect, DT_CALCRECT | DT_SINGLELINE, D3DCOLOR_XRGB(0, 0, 0));
pDXFont->DrawTextW(nullptr, strText.c_str(), strText.length(), &rect, DT_CALCRECT | DT_SINGLELINE, D3DCOLOR_XRGB(0, 0, 0));

return ((float)(rect.right - rect.left + iAdditionalPixels) * fScale);
}
@@ -724,6 +704,63 @@ float CGraphics::GetDXTextExtentW(const wchar_t* wszText, float fScale, LPD3DXFO
return 0.0f;
}

void CGraphics::GetDXTextSize(CVector2D& vecSize, const char* szText, float fWidth, float fScaleX, float fScaleY, LPD3DXFONT pDXFont, bool bWordBreak,
bool bColorCoded)
{
if (*szText == '\0')
return;

if (!pDXFont)
pDXFont = GetFont();

pDXFont = MaybeGetBigFont(pDXFont, fScaleX, fScaleY);

if (pDXFont)
{
WString strText = MbUTF8ToUTF16(szText);

if (bColorCoded)
RemoveColorCodesInPlaceW(strText);

ulong ulFormat = DT_CALCRECT;
if (bWordBreak)
ulFormat |= DT_WORDBREAK;

// Calculate the size of the text
RECT rect = {0, 0, fWidth / fScaleX, 0};
pDXFont->DrawTextW(nullptr, strText.c_str(), strText.length(), &rect, ulFormat, D3DCOLOR_XRGB(0, 0, 0));

vecSize.fX = (rect.right - rect.left) * fScaleX;
vecSize.fY = (rect.bottom - rect.top) * fScaleY;
}
}

int CGraphics::GetTrailingSpacesWidth(ID3DXFont* pDXFont, WString& strText)
{
// Count the amount of space characters at the end
int iSpaceCount = 0;
for (auto c = strText.rbegin(); c != strText.rend(); ++c)
{
if (*c == ' ')
++iSpaceCount;
else
break;
}

// Compute the size of a single space and use that
// to get the width of the ignored space characters
int iSpacesWidth = 0;
if (iSpaceCount > 0)
{
HDC dc = pDXFont->GetDC();
SIZE size;
GetTextExtentPoint32W(dc, L" ", 1, &size);
iSpacesWidth = iSpaceCount * size.cx;
}

return iSpacesWidth;
}

ID3DXFont* CGraphics::GetFont(eFontType fontType, float* pfOutScaleUsed, float fRequestedScale, const char* szCustomScaleUser)
{
if (pfOutScaleUsed)
@@ -121,6 +121,8 @@ class CGraphics : public CGraphicsInterface, public CSingleton<CGraphics>
float GetDXCharacterWidth(char c, float fScale = 1.0f, ID3DXFont* pDXFont = NULL);
float GetDXTextExtent(const char* szText, float fScale = 1.0f, ID3DXFont* pDXFont = NULL, bool bColorCoded = false);
float GetDXTextExtentW(const wchar_t* wszText, float fScale = 1.0f, LPD3DXFONT pDXFont = NULL);
void GetDXTextSize(CVector2D& vecSize, const char* szText, float fWidth = 0, float fScaleX = 1.0f, float fScaleY = 1.0f, LPD3DXFONT pDXFont = nullptr,
bool bWordBreak = false, bool bColorCoded = false);

// Textures
void DrawTexture(CTextureItem* texture, float fX, float fY, float fScaleX = 1.0f, float fScaleY = 1.0f, float fRotation = 0.0f, float fCenterX = 0.0f,
@@ -206,6 +208,7 @@ class CGraphics : public CGraphicsInterface, public CSingleton<CGraphics>
void DrawColorCodedTextLine(float fLeft, float fRight, float fY, SColor& currentColor, const wchar_t* wszText, float fScaleX, float fScaleY,
unsigned long ulFormat, ID3DXFont* pDXFont, bool bPostGUI, bool bSubPixelPositioning, float fRotation, float fRotationCenterX,
float fRotationCenterY);
int GetTrailingSpacesWidth(ID3DXFont* pDXFont, WString& strText);

CLocalGUI* m_pGUI;

@@ -10,7 +10,7 @@
*****************************************************************************/

#include "StdInc.h"
#define MIN_CLIENT_REQ_DXSETRENDERTARGET_CALL_RESTRICTIONS "1.3.0-9.04431"
#define MIN_CLIENT_REQ_DXSETRENDERTARGET_CALL_RESTRICTIONS "1.3.0-9.04431"
extern bool g_bAllowAspectRatioAdjustment;

void CLuaDrawingDefs::LoadFunctions()
@@ -31,6 +31,7 @@ void CLuaDrawingDefs::LoadFunctions()
{"dxDrawMaterialPrimitive3D", DxDrawMaterialPrimitive3D},
{"dxDrawWiredSphere", DxDrawWiredSphere},
{"dxGetTextWidth", DxGetTextWidth},
{"dxGetTextSize", DxGetTextSize},
{"dxGetFontHeight", DxGetFontHeight},
{"dxCreateFont", DxCreateFont},
{"dxCreateTexture", DxCreateTexture},
@@ -107,6 +108,7 @@ void CLuaDrawingDefs::AddDxFontClass(lua_State* luaVM)

lua_classfunction(luaVM, "getHeight", OOP_DxGetFontHeight);
lua_classfunction(luaVM, "getTextWidth", OOP_DxGetTextWidth);
lua_classfunction(luaVM, "getTextSize", OOP_DxGetTextSize);

// lua_classvariable ( luaVM, "height", NULL, "dxGetFontHeight"); // swap arguments, .height[scale] = int(height);

@@ -854,6 +856,100 @@ int CLuaDrawingDefs::OOP_DxGetTextWidth(lua_State* luaVM)
return 1;
}

int CLuaDrawingDefs::DxGetTextSize(lua_State* luaVM)
{
// float, float dxGetTextSize ( string text, [float width=0, float scaleXY=1.0, float=scaleY=1.0, mixed font="default",
// bool wordBreak=false, bool colorCoded=false] )
SString strText;
float fWidth;
float fScaleX;
float fScaleY;
eFontType fontType;
CClientDxFont* pDxFontElement;
bool bWordBreak;
bool bColorCoded;

CScriptArgReader argStream(luaVM);
argStream.ReadString(strText);
argStream.ReadNumber(fWidth, 0);
if (argStream.NextIsUserDataOfType<CLuaVector2D>())
{
CVector2D vecScale;
argStream.ReadVector2D(vecScale);
fScaleX = vecScale.fX;
fScaleY = vecScale.fY;
}
else
{
argStream.ReadNumber(fScaleX, 1);
if (argStream.NextIsNumber())
argStream.ReadNumber(fScaleY);
else
fScaleY = fScaleX;
}
MixedReadDxFontString(argStream, fontType, FONT_DEFAULT, pDxFontElement);
argStream.ReadBool(bWordBreak, false);
argStream.ReadBool(bColorCoded, false);

if (argStream.HasErrors())
return luaL_error(luaVM, argStream.GetFullErrorMessage());

// Get DX font
ID3DXFont* pD3DXFont = CStaticFunctionDefinitions::ResolveD3DXFont(fontType, pDxFontElement);

CVector2D vecSize;
g_pCore->GetGraphics()->GetDXTextSize(vecSize, strText.c_str(), fWidth, fScaleX, fScaleY, pD3DXFont, bWordBreak, bColorCoded);
lua_pushnumber(luaVM, vecSize.fX);
lua_pushnumber(luaVM, vecSize.fY);
return 2;
}

int CLuaDrawingDefs::OOP_DxGetTextSize(lua_State* luaVM)
{
// vector2 DxFont:getTextSize ( string text, [float width=0, float scaleXY=1.0, float=scaleY=1.0,
// bool wordBreak=false, bool colorCoded=false] )
SString strText;
float fWidth;
float fScaleX;
float fScaleY;
CClientDxFont* pDxFontElement;
bool bWordBreak;
bool bColorCoded;

CScriptArgReader argStream(luaVM);
argStream.ReadUserData(pDxFontElement);
argStream.ReadString(strText);
argStream.ReadNumber(fWidth, 0);
if (argStream.NextIsUserDataOfType<CLuaVector2D>())
{
CVector2D vecScale;
argStream.ReadVector2D(vecScale);
fScaleX = vecScale.fX;
fScaleY = vecScale.fY;
}
else
{
argStream.ReadNumber(fScaleX, 1);
if (argStream.NextIsNumber())
argStream.ReadNumber(fScaleY);
else
fScaleY = fScaleX;
}
argStream.ReadBool(bWordBreak, false);
argStream.ReadBool(bColorCoded, false);

if (argStream.HasErrors())
return luaL_error(luaVM, argStream.GetFullErrorMessage());

// Get DX font
ID3DXFont* pD3DXFont = CStaticFunctionDefinitions::ResolveD3DXFont(FONT_DEFAULT, pDxFontElement);

CVector2D vecSize;
g_pCore->GetGraphics()->GetDXTextSize(vecSize, strText.c_str(), fWidth, fScaleX, fScaleY, pD3DXFont, bWordBreak, bColorCoded);
lua_pushvector(luaVM, vecSize);
return 1;
}

int CLuaDrawingDefs::DxGetFontHeight(lua_State* luaVM)
{
// int dxGetFontHeight ( [float scale=1, mixed font="default"] )
@@ -1084,10 +1180,8 @@ int CLuaDrawingDefs::DxCreateShader(lua_State* luaVM)

if (!bIsRawData)
{
bIsRawData = (strFile.find("technique ") != std::string::npos) &&
(strFile.find("pass ") != std::string::npos) &&
(strFile.find('{') != std::string::npos) &&
(strFile.find('}') != std::string::npos);
bIsRawData = (strFile.find("technique ") != std::string::npos) && (strFile.find("pass ") != std::string::npos) &&
(strFile.find('{') != std::string::npos) && (strFile.find('}') != std::string::npos);
}
}

@@ -1113,8 +1207,8 @@ int CLuaDrawingDefs::DxCreateShader(lua_State* luaVM)
}

SString strStatus;
CClientShader* pShader = g_pClientGame->GetManager()->GetRenderElementManager()->CreateShader(
strPath, strRootPath, bIsRawData, strStatus, fPriority, fMaxDistance, bLayered, false, iEntityTypeMaskResult);
CClientShader* pShader = g_pClientGame->GetManager()->GetRenderElementManager()->CreateShader(strPath, strRootPath, bIsRawData, strStatus, fPriority,
fMaxDistance, bLayered, false, iEntityTypeMaskResult);

if (pShader)
{
@@ -31,6 +31,7 @@ class CLuaDrawingDefs : public CLuaDefs
LUA_DECLARE(DxDrawMaterialPrimitive);
LUA_DECLARE(DxDrawPrimitive3D);
LUA_DECLARE(DxDrawMaterialPrimitive3D);
LUA_DECLARE_OOP(DxGetTextSize);
LUA_DECLARE(DxDrawWiredSphere);
LUA_DECLARE_OOP(DxGetTextWidth);
LUA_DECLARE_OOP(DxGetFontHeight);
@@ -127,6 +127,7 @@ class CGraphicsInterface
virtual float GetDXFontHeight(float fScale = 1.0f, ID3DXFont* pDXFont = NULL) = 0;
virtual float GetDXCharacterWidth(char c, float fScale = 1.0f, ID3DXFont* pDXFont = NULL) = 0;
virtual float GetDXTextExtent(const char* szText, float fScale = 1.0f, ID3DXFont* pDXFont = NULL, bool bColorCoded = false) = 0;
virtual void GetDXTextSize(CVector2D& vecSize, const char* szText, float fWidth = 0, float fScaleX = 1.0f, float fScaleY = 1.0f, ID3DXFont* pDXFont = nullptr, bool bWordBreak = false, bool bColorCoded = false) = 0;

virtual bool LoadAdditionalDXFont(std::string strFontPath, std::string strFontName, unsigned int uiHeight, bool bBold, ID3DXFont** ppD3DXFont) = 0;
virtual bool LoadAdditionalDXFont(std::string strFontPath, std::string strFontName, unsigned int uiHeight, bool bBold, DWORD ulQuality,

0 comments on commit f6be063

Please sign in to comment.
You can’t perform that action at this time.