mirror of
https://github.com/whoahq/whoa.git
synced 2026-02-01 00:02:45 +03:00
chore(gx): extract TextBlock functions into dedicated unit
This commit is contained in:
parent
eee9322da9
commit
d3c3c21237
316
src/gx/Font.cpp
316
src/gx/Font.cpp
@ -1,87 +1,15 @@
|
|||||||
#include "gx/Font.hpp"
|
#include "gx/Font.hpp"
|
||||||
#include "gx/Coordinate.hpp"
|
|
||||||
#include "gx/Device.hpp"
|
|
||||||
#include "gx/font/CGxFont.hpp"
|
#include "gx/font/CGxFont.hpp"
|
||||||
#include "gx/font/GxuFont.hpp"
|
#include "gx/font/GxuFont.hpp"
|
||||||
#include <storm/Error.hpp>
|
|
||||||
#include <storm/Memory.hpp>
|
|
||||||
#include <storm/String.hpp>
|
|
||||||
#include <tempest/Math.hpp>
|
#include <tempest/Math.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
CGxShader* g_fontPixelShader[1];
|
|
||||||
CGxShader* g_fontVertexShader[2];
|
|
||||||
TSHashTable<FONTHASHOBJ, HASHKEY_STR> s_fontHash;
|
|
||||||
uint32_t g_heightPixels;
|
uint32_t g_heightPixels;
|
||||||
uint32_t g_widthPixels;
|
uint32_t g_widthPixels;
|
||||||
float g_indentPixelWidth;
|
float g_indentPixelWidth;
|
||||||
float g_indentNormWidth;
|
float g_indentNormWidth;
|
||||||
|
|
||||||
FONTHASHOBJ::~FONTHASHOBJ() {
|
|
||||||
if (this->font) {
|
|
||||||
GxuFontDestroyFont(this->font);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEXTBLOCK::~TEXTBLOCK() {
|
|
||||||
GxuFontDestroyString(this->string);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ConvertStringFlags(uint32_t flags) {
|
|
||||||
uint32_t convertedFlags = 0x0;
|
|
||||||
|
|
||||||
if (flags & 0x100) {
|
|
||||||
convertedFlags |= 0x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & 0x200) {
|
|
||||||
convertedFlags |= 0x4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & 0x400) {
|
|
||||||
convertedFlags |= 0x8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & 0x800) {
|
|
||||||
convertedFlags |= 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & 0x40) {
|
|
||||||
convertedFlags |= 0x2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & 0x1000) {
|
|
||||||
convertedFlags |= 0x40;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & 0x2000) {
|
|
||||||
convertedFlags |= 0x100;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & 0x4000) {
|
|
||||||
convertedFlags |= 0x200;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & 0x8000) {
|
|
||||||
convertedFlags |= 0x400;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & 0x80) {
|
|
||||||
convertedFlags |= 0x800;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & 0x10000) {
|
|
||||||
convertedFlags |= 0x1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & 0x20000) {
|
|
||||||
convertedFlags |= 0x2000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return convertedFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
float GetCharacterWidth(const char* text, uint32_t flags, uint32_t prevCode, CGxFont* font, float a5) {
|
float GetCharacterWidth(const char* text, uint32_t flags, uint32_t prevCode, CGxFont* font, float a5) {
|
||||||
if (!prevCode) {
|
if (!prevCode) {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
@ -193,247 +121,3 @@ float Sub6C2280(FT_Face face, float height) {
|
|||||||
return v7 >= height ? v7 : height;
|
return v7 >= height ? v7 : height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBlockAddShadow(HTEXTBLOCK string, CImVector color, const C2Vector& offset) {
|
|
||||||
STORM_ASSERT(string);
|
|
||||||
|
|
||||||
C2Vector ndcOffset;
|
|
||||||
DDCToNDC(offset.x, offset.y, &ndcOffset.x, &ndcOffset.y);
|
|
||||||
|
|
||||||
GxuFontAddShadow(TextBlockGetStringPtr(string), color, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
HTEXTBLOCK TextBlockCreate(HTEXTFONT fontHandle, const char* text, const CImVector& color, const C3Vector& position, float fontHeight, float blockWidth, float blockHeight, uint32_t flags, float charSpacing, float lineSpacing, float scale) {
|
|
||||||
STORM_VALIDATE_BEGIN;
|
|
||||||
STORM_VALIDATE(fontHandle);
|
|
||||||
STORM_VALIDATE(text);
|
|
||||||
STORM_VALIDATE_END;
|
|
||||||
|
|
||||||
auto textBlock = STORM_NEW(TEXTBLOCK)();
|
|
||||||
|
|
||||||
C3Vector ndcPosition = { 0.0f, 0.0f, position.z };
|
|
||||||
DDCToNDC(position.x, position.y, &ndcPosition.x, &ndcPosition.y);
|
|
||||||
|
|
||||||
EGxFontHJusts hjust = GxHJ_Center;
|
|
||||||
|
|
||||||
if (flags & 0x4) {
|
|
||||||
hjust = GxHJ_Right;
|
|
||||||
} else if (!(flags & 0x2) && flags & 0x1) {
|
|
||||||
hjust = GxHJ_Left;
|
|
||||||
}
|
|
||||||
|
|
||||||
EGxFontVJusts vjust = GxVJ_Middle;
|
|
||||||
|
|
||||||
if (flags & 0x8) {
|
|
||||||
vjust = GxVJ_Top;
|
|
||||||
} else if (flags & 0x20) {
|
|
||||||
vjust = GxVJ_Bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t stringFlags = ConvertStringFlags(flags);
|
|
||||||
|
|
||||||
float ndcCharSpacing = DDCToNDCWidth(charSpacing);
|
|
||||||
float ndcLineSpacing = DDCToNDCHeight(lineSpacing);
|
|
||||||
float ndcBlockHeight = DDCToNDCHeight(blockHeight);
|
|
||||||
float ndcBlockWidth = DDCToNDCWidth(blockWidth);
|
|
||||||
float ndcFontHeight = DDCToNDCHeight(fontHeight);
|
|
||||||
|
|
||||||
GxuFontCreateString(
|
|
||||||
reinterpret_cast<FONTHASHOBJ*>(fontHandle)->font,
|
|
||||||
text,
|
|
||||||
ndcFontHeight,
|
|
||||||
ndcPosition,
|
|
||||||
ndcBlockWidth,
|
|
||||||
ndcBlockHeight,
|
|
||||||
ndcLineSpacing,
|
|
||||||
textBlock->string,
|
|
||||||
vjust,
|
|
||||||
hjust,
|
|
||||||
stringFlags,
|
|
||||||
color,
|
|
||||||
ndcCharSpacing,
|
|
||||||
scale
|
|
||||||
);
|
|
||||||
|
|
||||||
return HandleCreate(textBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
HTEXTFONT TextBlockGenerateFont(const char* fontName, uint32_t fontFlags, float fontHeight) {
|
|
||||||
STORM_ASSERT(fontName);
|
|
||||||
STORM_ASSERT(*fontName);
|
|
||||||
|
|
||||||
float fontHeightNDC = DDCToNDCHeight(fontHeight);
|
|
||||||
|
|
||||||
if (fontHeightNDC >= 1.0) {
|
|
||||||
fontHeightNDC = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char hashKey[276];
|
|
||||||
|
|
||||||
SStrPrintf(hashKey, 276, "%s-%d-%f", fontName, fontFlags, fontHeightNDC);
|
|
||||||
|
|
||||||
auto v7 = s_fontHash.Ptr(hashKey);
|
|
||||||
|
|
||||||
if (v7) {
|
|
||||||
return HandleCreate(v7);
|
|
||||||
}
|
|
||||||
|
|
||||||
v7 = s_fontHash.New(hashKey, 0, 0);
|
|
||||||
|
|
||||||
uint32_t v14 = 0;
|
|
||||||
|
|
||||||
if (fontFlags & FONT_OUTLINE) {
|
|
||||||
v14 |= 0x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fontFlags & FONT_THICKOUTLINE) {
|
|
||||||
v14 |= 0x8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fontFlags & FONT_MONOCHROME) {
|
|
||||||
v14 |= 0x2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GxuFontCreateFont(fontName, fontHeightNDC, v7->font, v14)) {
|
|
||||||
return HandleCreate(v7);
|
|
||||||
} else {
|
|
||||||
// TODO
|
|
||||||
// sub_723270(v12);
|
|
||||||
// (s_fontHash)(&s_fontHash, v12);
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t TextBlockGetFontFlags(HTEXTFONT fontHandle) {
|
|
||||||
STORM_ASSERT(fontHandle);
|
|
||||||
|
|
||||||
uint32_t gxFlags = GxuFontGetFontFlags(TextBlockGetFontPtr(fontHandle));
|
|
||||||
uint32_t flags = 0;
|
|
||||||
|
|
||||||
if (gxFlags & 0x1) {
|
|
||||||
flags |= 0x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gxFlags & 0x2) {
|
|
||||||
flags |= 0x2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gxFlags & 0x8) {
|
|
||||||
flags |= 0x4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* TextBlockGetFontName(HTEXTFONT fontHandle) {
|
|
||||||
STORM_ASSERT(fontHandle);
|
|
||||||
|
|
||||||
return GxuFontGetFontName(reinterpret_cast<FONTHASHOBJ*>(fontHandle)->font);
|
|
||||||
}
|
|
||||||
|
|
||||||
CGxFont* TextBlockGetFontPtr(HTEXTFONT fontHandle) {
|
|
||||||
STORM_ASSERT(fontHandle);
|
|
||||||
|
|
||||||
return reinterpret_cast<FONTHASHOBJ*>(fontHandle)->font;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t TextBlockGetMaxCharsWithinWidth(HTEXTFONT fontHandle, const char* text, float height, float maxWidth, uint32_t lineBytes, float* extent, float a7, float scale, float a9, uint32_t flags) {
|
|
||||||
STORM_ASSERT(fontHandle);
|
|
||||||
STORM_ASSERT(text);
|
|
||||||
|
|
||||||
return GxuFontGetMaxCharsWithinWidth(
|
|
||||||
TextBlockGetFontPtr(fontHandle),
|
|
||||||
text,
|
|
||||||
DDCToNDCHeight(height),
|
|
||||||
DDCToNDCWidth(maxWidth),
|
|
||||||
lineBytes,
|
|
||||||
extent,
|
|
||||||
DDCToNDCWidth(a7),
|
|
||||||
scale,
|
|
||||||
DDCToNDCWidth(a9),
|
|
||||||
ConvertStringFlags(flags)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t TextBlockGetMaxCharsWithinWidthAndHeight(HTEXTFONT fontHandle, const char* text, float height, float maxWidth, float maxHeight, uint32_t lineBytes, float a7, float scale, float a9, uint32_t flags) {
|
|
||||||
STORM_ASSERT(fontHandle);
|
|
||||||
STORM_ASSERT(text);
|
|
||||||
|
|
||||||
return GxuFontGetMaxCharsWithinWidthAndHeight(
|
|
||||||
TextBlockGetFontPtr(fontHandle),
|
|
||||||
text,
|
|
||||||
DDCToNDCHeight(height),
|
|
||||||
DDCToNDCWidth(maxWidth),
|
|
||||||
DDCToNDCHeight(maxHeight),
|
|
||||||
lineBytes,
|
|
||||||
DDCToNDCWidth(a7),
|
|
||||||
scale,
|
|
||||||
DDCToNDCHeight(a9),
|
|
||||||
ConvertStringFlags(flags)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
CGxString* TextBlockGetStringPtr(HTEXTBLOCK stringHandle) {
|
|
||||||
STORM_ASSERT(stringHandle);
|
|
||||||
|
|
||||||
return reinterpret_cast<TEXTBLOCK*>(stringHandle)->string;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextBlockGetTextExtent(HTEXTFONT fontHandle, const char* text, uint32_t numChars, float fontHeight, float* extent, float a6, float scale, float a8, uint32_t flags) {
|
|
||||||
STORM_ASSERT(fontHandle);
|
|
||||||
STORM_ASSERT(text);
|
|
||||||
STORM_ASSERT(extent);
|
|
||||||
|
|
||||||
*extent = 0.0f;
|
|
||||||
|
|
||||||
GxuFontGetTextExtent(
|
|
||||||
TextBlockGetFontPtr(fontHandle),
|
|
||||||
text,
|
|
||||||
numChars,
|
|
||||||
DDCToNDCHeight(fontHeight),
|
|
||||||
extent,
|
|
||||||
DDCToNDCWidth(a6),
|
|
||||||
scale,
|
|
||||||
DDCToNDCWidth(a8),
|
|
||||||
ConvertStringFlags(flags)
|
|
||||||
);
|
|
||||||
|
|
||||||
NDCToDDC(*extent, 0.0f, extent, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
float TextBlockGetWrappedTextHeight(HTEXTFONT fontHandle, const char* text, float a3, float a4, const C2Vector& a5, float a6, float a7, uint32_t flags) {
|
|
||||||
STORM_ASSERT(fontHandle);
|
|
||||||
STORM_ASSERT(text);
|
|
||||||
|
|
||||||
float shadowWidth;
|
|
||||||
float shadowHeight;
|
|
||||||
DDCToNDC(a5.x, a5.y, &shadowWidth, &shadowHeight);
|
|
||||||
C2Vector shadowSize = { shadowWidth, shadowHeight };
|
|
||||||
|
|
||||||
float height = GxuFontGetWrappedTextHeight(
|
|
||||||
TextBlockGetFontPtr(fontHandle),
|
|
||||||
text,
|
|
||||||
DDCToNDCHeight(a3),
|
|
||||||
DDCToNDCWidth(a4),
|
|
||||||
shadowSize,
|
|
||||||
a6,
|
|
||||||
DDCToNDCHeight(a7),
|
|
||||||
ConvertStringFlags(flags)
|
|
||||||
);
|
|
||||||
|
|
||||||
return NDCToDDCHeight(height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextBlockSetStringPos(HTEXTBLOCK stringHandle, const C3Vector& pos) {
|
|
||||||
STORM_ASSERT(stringHandle);
|
|
||||||
|
|
||||||
C3Vector ndcPos = { 0.0f, 0.0f, pos.z };
|
|
||||||
DDCToNDC(pos.x, pos.y, &ndcPos.x, &ndcPos.y);
|
|
||||||
GxuFontSetStringPosition(TextBlockGetStringPtr(stringHandle), ndcPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextBlockUpdateColor(HTEXTBLOCK stringHandle, const CImVector& color) {
|
|
||||||
STORM_ASSERT(stringHandle);
|
|
||||||
|
|
||||||
GxuFontSetStringColor(TextBlockGetStringPtr(stringHandle), color);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -3,37 +3,13 @@
|
|||||||
|
|
||||||
#include "gx/font/FreeType.hpp"
|
#include "gx/font/FreeType.hpp"
|
||||||
#include "gx/font/GxuFont.hpp"
|
#include "gx/font/GxuFont.hpp"
|
||||||
#include "gx/font/Types.hpp"
|
#include "gx/font/TextBlock.hpp"
|
||||||
#include <common/Handle.hpp>
|
#include <cstdint>
|
||||||
#include <storm/Hash.hpp>
|
|
||||||
|
|
||||||
#define FONT_OUTLINE 0x1
|
|
||||||
#define FONT_MONOCHROME 0x2
|
|
||||||
#define FONT_THICKOUTLINE 0x4
|
|
||||||
|
|
||||||
class C2Vector;
|
class C2Vector;
|
||||||
class C3Vector;
|
class C3Vector;
|
||||||
class CGxFont;
|
class CGxFont;
|
||||||
class CGxShader;
|
|
||||||
class CGxString;
|
|
||||||
class CGxStringBatch;
|
|
||||||
class CImVector;
|
|
||||||
struct GLYPHBITMAPDATA;
|
|
||||||
|
|
||||||
class FONTHASHOBJ : public CHandleObject, public TSHashObject<FONTHASHOBJ, HASHKEY_STR> {
|
|
||||||
public:
|
|
||||||
CGxFont* font = nullptr;
|
|
||||||
virtual ~FONTHASHOBJ();
|
|
||||||
};
|
|
||||||
|
|
||||||
class TEXTBLOCK : public CHandleObject {
|
|
||||||
public:
|
|
||||||
CGxString* string = nullptr;
|
|
||||||
virtual ~TEXTBLOCK();
|
|
||||||
};
|
|
||||||
|
|
||||||
extern CGxShader* g_fontPixelShader[1];
|
|
||||||
extern CGxShader* g_fontVertexShader[2];
|
|
||||||
extern uint32_t g_heightPixels;
|
extern uint32_t g_heightPixels;
|
||||||
extern uint32_t g_widthPixels;
|
extern uint32_t g_widthPixels;
|
||||||
extern float g_indentPixelWidth;
|
extern float g_indentPixelWidth;
|
||||||
@ -43,37 +19,11 @@ float GetCharacterWidth(const char*, uint32_t, uint32_t, CGxFont*, float);
|
|||||||
|
|
||||||
float GetIndentNormWidth();
|
float GetIndentNormWidth();
|
||||||
|
|
||||||
float GetIndentPixelWidth(void);
|
float GetIndentPixelWidth();
|
||||||
|
|
||||||
uint32_t GetScreenPixelHeight(void);
|
uint32_t GetScreenPixelHeight();
|
||||||
|
|
||||||
uint32_t GetScreenPixelWidth(void);
|
uint32_t GetScreenPixelWidth();
|
||||||
|
|
||||||
void TextBlockAddShadow(HTEXTBLOCK, CImVector, const C2Vector&);
|
|
||||||
|
|
||||||
HTEXTBLOCK TextBlockCreate(HTEXTFONT fontHandle, const char* text, const CImVector& color, const C3Vector& position, float fontHeight, float blockWidth, float blockHeight, uint32_t flags, float charSpacing, float lineSpacing, float scale);
|
|
||||||
|
|
||||||
HTEXTFONT TextBlockGenerateFont(const char*, uint32_t, float);
|
|
||||||
|
|
||||||
uint32_t TextBlockGetFontFlags(HTEXTFONT);
|
|
||||||
|
|
||||||
const char* TextBlockGetFontName(HTEXTFONT);
|
|
||||||
|
|
||||||
CGxFont* TextBlockGetFontPtr(HTEXTFONT);
|
|
||||||
|
|
||||||
uint32_t TextBlockGetMaxCharsWithinWidth(HTEXTFONT, const char*, float, float, uint32_t, float*, float, float, float, uint32_t);
|
|
||||||
|
|
||||||
uint32_t TextBlockGetMaxCharsWithinWidthAndHeight(HTEXTFONT, const char*, float, float, float, uint32_t, float, float, float, uint32_t);
|
|
||||||
|
|
||||||
CGxString* TextBlockGetStringPtr(HTEXTBLOCK);
|
|
||||||
|
|
||||||
void TextBlockGetTextExtent(HTEXTFONT, const char*, uint32_t, float, float*, float, float, float, uint32_t);
|
|
||||||
|
|
||||||
float TextBlockGetWrappedTextHeight(HTEXTFONT, const char*, float, float, const C2Vector&, float, float, uint32_t);
|
|
||||||
|
|
||||||
void TextBlockSetStringPos(HTEXTBLOCK stringHandle, const C3Vector& pos);
|
|
||||||
|
|
||||||
void TextBlockUpdateColor(HTEXTBLOCK, const CImVector&);
|
|
||||||
|
|
||||||
float PixelToScreenHeight(int32_t);
|
float PixelToScreenHeight(int32_t);
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,8 @@
|
|||||||
#include <tempest/Math.hpp>
|
#include <tempest/Math.hpp>
|
||||||
#include <tempest/Rect.hpp>
|
#include <tempest/Rect.hpp>
|
||||||
|
|
||||||
|
CGxShader* g_fontPixelShader[1];
|
||||||
|
CGxShader* g_fontVertexShader[2];
|
||||||
STORM_LIST(CGxFont) g_fonts;
|
STORM_LIST(CGxFont) g_fonts;
|
||||||
STORM_LIST(CGxString) g_freeStrings;
|
STORM_LIST(CGxString) g_freeStrings;
|
||||||
STORM_LIST(CGxString) g_strings;
|
STORM_LIST(CGxString) g_strings;
|
||||||
|
|||||||
@ -8,9 +8,12 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
class CGxFont;
|
class CGxFont;
|
||||||
|
class CGxShader;
|
||||||
class CGxString;
|
class CGxString;
|
||||||
class CGxStringBatch;
|
class CGxStringBatch;
|
||||||
|
|
||||||
|
extern CGxShader* g_fontPixelShader[1];
|
||||||
|
extern CGxShader* g_fontVertexShader[2];
|
||||||
extern STORM_LIST(CGxFont) g_fonts;
|
extern STORM_LIST(CGxFont) g_fonts;
|
||||||
extern STORM_LIST(CGxString) g_freeStrings;
|
extern STORM_LIST(CGxString) g_freeStrings;
|
||||||
extern STORM_LIST(CGxString) g_strings;
|
extern STORM_LIST(CGxString) g_strings;
|
||||||
|
|||||||
316
src/gx/font/TextBlock.cpp
Normal file
316
src/gx/font/TextBlock.cpp
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
#include "gx/font/TextBlock.hpp"
|
||||||
|
#include "gx/Coordinate.hpp"
|
||||||
|
#include "gx/font/GxuFont.hpp"
|
||||||
|
#include <storm/Error.hpp>
|
||||||
|
#include <storm/Memory.hpp>
|
||||||
|
|
||||||
|
static TSHashTable<FONTHASHOBJ, HASHKEY_STR> s_fontHash;
|
||||||
|
|
||||||
|
FONTHASHOBJ::~FONTHASHOBJ() {
|
||||||
|
if (this->font) {
|
||||||
|
GxuFontDestroyFont(this->font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEXTBLOCK::~TEXTBLOCK() {
|
||||||
|
GxuFontDestroyString(this->string);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ConvertStringFlags(uint32_t flags) {
|
||||||
|
uint32_t convertedFlags = 0x0;
|
||||||
|
|
||||||
|
if (flags & 0x100) {
|
||||||
|
convertedFlags |= 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 0x200) {
|
||||||
|
convertedFlags |= 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 0x400) {
|
||||||
|
convertedFlags |= 0x8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 0x800) {
|
||||||
|
convertedFlags |= 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 0x40) {
|
||||||
|
convertedFlags |= 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 0x1000) {
|
||||||
|
convertedFlags |= 0x40;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 0x2000) {
|
||||||
|
convertedFlags |= 0x100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 0x4000) {
|
||||||
|
convertedFlags |= 0x200;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 0x8000) {
|
||||||
|
convertedFlags |= 0x400;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 0x80) {
|
||||||
|
convertedFlags |= 0x800;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 0x10000) {
|
||||||
|
convertedFlags |= 0x1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 0x20000) {
|
||||||
|
convertedFlags |= 0x2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return convertedFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBlockAddShadow(HTEXTBLOCK string, CImVector color, const C2Vector& offset) {
|
||||||
|
STORM_ASSERT(string);
|
||||||
|
|
||||||
|
C2Vector ndcOffset;
|
||||||
|
DDCToNDC(offset.x, offset.y, &ndcOffset.x, &ndcOffset.y);
|
||||||
|
|
||||||
|
GxuFontAddShadow(TextBlockGetStringPtr(string), color, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
HTEXTBLOCK TextBlockCreate(HTEXTFONT fontHandle, const char* text, const CImVector& color, const C3Vector& position, float fontHeight, float blockWidth, float blockHeight, uint32_t flags, float charSpacing, float lineSpacing, float scale) {
|
||||||
|
STORM_VALIDATE_BEGIN;
|
||||||
|
STORM_VALIDATE(fontHandle);
|
||||||
|
STORM_VALIDATE(text);
|
||||||
|
STORM_VALIDATE_END;
|
||||||
|
|
||||||
|
auto textBlock = STORM_NEW(TEXTBLOCK)();
|
||||||
|
|
||||||
|
C3Vector ndcPosition = { 0.0f, 0.0f, position.z };
|
||||||
|
DDCToNDC(position.x, position.y, &ndcPosition.x, &ndcPosition.y);
|
||||||
|
|
||||||
|
EGxFontHJusts hjust = GxHJ_Center;
|
||||||
|
|
||||||
|
if (flags & 0x4) {
|
||||||
|
hjust = GxHJ_Right;
|
||||||
|
} else if (!(flags & 0x2) && flags & 0x1) {
|
||||||
|
hjust = GxHJ_Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGxFontVJusts vjust = GxVJ_Middle;
|
||||||
|
|
||||||
|
if (flags & 0x8) {
|
||||||
|
vjust = GxVJ_Top;
|
||||||
|
} else if (flags & 0x20) {
|
||||||
|
vjust = GxVJ_Bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t stringFlags = ConvertStringFlags(flags);
|
||||||
|
|
||||||
|
float ndcCharSpacing = DDCToNDCWidth(charSpacing);
|
||||||
|
float ndcLineSpacing = DDCToNDCHeight(lineSpacing);
|
||||||
|
float ndcBlockHeight = DDCToNDCHeight(blockHeight);
|
||||||
|
float ndcBlockWidth = DDCToNDCWidth(blockWidth);
|
||||||
|
float ndcFontHeight = DDCToNDCHeight(fontHeight);
|
||||||
|
|
||||||
|
GxuFontCreateString(
|
||||||
|
reinterpret_cast<FONTHASHOBJ*>(fontHandle)->font,
|
||||||
|
text,
|
||||||
|
ndcFontHeight,
|
||||||
|
ndcPosition,
|
||||||
|
ndcBlockWidth,
|
||||||
|
ndcBlockHeight,
|
||||||
|
ndcLineSpacing,
|
||||||
|
textBlock->string,
|
||||||
|
vjust,
|
||||||
|
hjust,
|
||||||
|
stringFlags,
|
||||||
|
color,
|
||||||
|
ndcCharSpacing,
|
||||||
|
scale
|
||||||
|
);
|
||||||
|
|
||||||
|
return HandleCreate(textBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
HTEXTFONT TextBlockGenerateFont(const char* fontName, uint32_t fontFlags, float fontHeight) {
|
||||||
|
STORM_ASSERT(fontName);
|
||||||
|
STORM_ASSERT(*fontName);
|
||||||
|
|
||||||
|
float fontHeightNDC = DDCToNDCHeight(fontHeight);
|
||||||
|
|
||||||
|
if (fontHeightNDC >= 1.0) {
|
||||||
|
fontHeightNDC = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char hashKey[276];
|
||||||
|
|
||||||
|
SStrPrintf(hashKey, 276, "%s-%d-%f", fontName, fontFlags, fontHeightNDC);
|
||||||
|
|
||||||
|
auto v7 = s_fontHash.Ptr(hashKey);
|
||||||
|
|
||||||
|
if (v7) {
|
||||||
|
return HandleCreate(v7);
|
||||||
|
}
|
||||||
|
|
||||||
|
v7 = s_fontHash.New(hashKey, 0, 0);
|
||||||
|
|
||||||
|
uint32_t v14 = 0;
|
||||||
|
|
||||||
|
if (fontFlags & FONT_OUTLINE) {
|
||||||
|
v14 |= 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fontFlags & FONT_THICKOUTLINE) {
|
||||||
|
v14 |= 0x8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fontFlags & FONT_MONOCHROME) {
|
||||||
|
v14 |= 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GxuFontCreateFont(fontName, fontHeightNDC, v7->font, v14)) {
|
||||||
|
return HandleCreate(v7);
|
||||||
|
} else {
|
||||||
|
// TODO
|
||||||
|
// sub_723270(v12);
|
||||||
|
// (s_fontHash)(&s_fontHash, v12);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TextBlockGetFontFlags(HTEXTFONT fontHandle) {
|
||||||
|
STORM_ASSERT(fontHandle);
|
||||||
|
|
||||||
|
uint32_t gxFlags = GxuFontGetFontFlags(TextBlockGetFontPtr(fontHandle));
|
||||||
|
uint32_t flags = 0;
|
||||||
|
|
||||||
|
if (gxFlags & 0x1) {
|
||||||
|
flags |= 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gxFlags & 0x2) {
|
||||||
|
flags |= 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gxFlags & 0x8) {
|
||||||
|
flags |= 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* TextBlockGetFontName(HTEXTFONT fontHandle) {
|
||||||
|
STORM_ASSERT(fontHandle);
|
||||||
|
|
||||||
|
return GxuFontGetFontName(reinterpret_cast<FONTHASHOBJ*>(fontHandle)->font);
|
||||||
|
}
|
||||||
|
|
||||||
|
CGxFont* TextBlockGetFontPtr(HTEXTFONT fontHandle) {
|
||||||
|
STORM_ASSERT(fontHandle);
|
||||||
|
|
||||||
|
return reinterpret_cast<FONTHASHOBJ*>(fontHandle)->font;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TextBlockGetMaxCharsWithinWidth(HTEXTFONT fontHandle, const char* text, float height, float maxWidth, uint32_t lineBytes, float* extent, float a7, float scale, float a9, uint32_t flags) {
|
||||||
|
STORM_ASSERT(fontHandle);
|
||||||
|
STORM_ASSERT(text);
|
||||||
|
|
||||||
|
return GxuFontGetMaxCharsWithinWidth(
|
||||||
|
TextBlockGetFontPtr(fontHandle),
|
||||||
|
text,
|
||||||
|
DDCToNDCHeight(height),
|
||||||
|
DDCToNDCWidth(maxWidth),
|
||||||
|
lineBytes,
|
||||||
|
extent,
|
||||||
|
DDCToNDCWidth(a7),
|
||||||
|
scale,
|
||||||
|
DDCToNDCWidth(a9),
|
||||||
|
ConvertStringFlags(flags)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TextBlockGetMaxCharsWithinWidthAndHeight(HTEXTFONT fontHandle, const char* text, float height, float maxWidth, float maxHeight, uint32_t lineBytes, float a7, float scale, float a9, uint32_t flags) {
|
||||||
|
STORM_ASSERT(fontHandle);
|
||||||
|
STORM_ASSERT(text);
|
||||||
|
|
||||||
|
return GxuFontGetMaxCharsWithinWidthAndHeight(
|
||||||
|
TextBlockGetFontPtr(fontHandle),
|
||||||
|
text,
|
||||||
|
DDCToNDCHeight(height),
|
||||||
|
DDCToNDCWidth(maxWidth),
|
||||||
|
DDCToNDCHeight(maxHeight),
|
||||||
|
lineBytes,
|
||||||
|
DDCToNDCWidth(a7),
|
||||||
|
scale,
|
||||||
|
DDCToNDCHeight(a9),
|
||||||
|
ConvertStringFlags(flags)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
CGxString* TextBlockGetStringPtr(HTEXTBLOCK stringHandle) {
|
||||||
|
STORM_ASSERT(stringHandle);
|
||||||
|
|
||||||
|
return reinterpret_cast<TEXTBLOCK*>(stringHandle)->string;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBlockGetTextExtent(HTEXTFONT fontHandle, const char* text, uint32_t numChars, float fontHeight, float* extent, float a6, float scale, float a8, uint32_t flags) {
|
||||||
|
STORM_ASSERT(fontHandle);
|
||||||
|
STORM_ASSERT(text);
|
||||||
|
STORM_ASSERT(extent);
|
||||||
|
|
||||||
|
*extent = 0.0f;
|
||||||
|
|
||||||
|
GxuFontGetTextExtent(
|
||||||
|
TextBlockGetFontPtr(fontHandle),
|
||||||
|
text,
|
||||||
|
numChars,
|
||||||
|
DDCToNDCHeight(fontHeight),
|
||||||
|
extent,
|
||||||
|
DDCToNDCWidth(a6),
|
||||||
|
scale,
|
||||||
|
DDCToNDCWidth(a8),
|
||||||
|
ConvertStringFlags(flags)
|
||||||
|
);
|
||||||
|
|
||||||
|
NDCToDDC(*extent, 0.0f, extent, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
float TextBlockGetWrappedTextHeight(HTEXTFONT fontHandle, const char* text, float a3, float a4, const C2Vector& a5, float a6, float a7, uint32_t flags) {
|
||||||
|
STORM_ASSERT(fontHandle);
|
||||||
|
STORM_ASSERT(text);
|
||||||
|
|
||||||
|
float shadowWidth;
|
||||||
|
float shadowHeight;
|
||||||
|
DDCToNDC(a5.x, a5.y, &shadowWidth, &shadowHeight);
|
||||||
|
C2Vector shadowSize = { shadowWidth, shadowHeight };
|
||||||
|
|
||||||
|
float height = GxuFontGetWrappedTextHeight(
|
||||||
|
TextBlockGetFontPtr(fontHandle),
|
||||||
|
text,
|
||||||
|
DDCToNDCHeight(a3),
|
||||||
|
DDCToNDCWidth(a4),
|
||||||
|
shadowSize,
|
||||||
|
a6,
|
||||||
|
DDCToNDCHeight(a7),
|
||||||
|
ConvertStringFlags(flags)
|
||||||
|
);
|
||||||
|
|
||||||
|
return NDCToDDCHeight(height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBlockSetStringPos(HTEXTBLOCK stringHandle, const C3Vector& pos) {
|
||||||
|
STORM_ASSERT(stringHandle);
|
||||||
|
|
||||||
|
C3Vector ndcPos = { 0.0f, 0.0f, pos.z };
|
||||||
|
DDCToNDC(pos.x, pos.y, &ndcPos.x, &ndcPos.y);
|
||||||
|
GxuFontSetStringPosition(TextBlockGetStringPtr(stringHandle), ndcPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBlockUpdateColor(HTEXTBLOCK stringHandle, const CImVector& color) {
|
||||||
|
STORM_ASSERT(stringHandle);
|
||||||
|
|
||||||
|
GxuFontSetStringColor(TextBlockGetStringPtr(stringHandle), color);
|
||||||
|
}
|
||||||
55
src/gx/font/TextBlock.hpp
Normal file
55
src/gx/font/TextBlock.hpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef GX_FONT_TEXT_BLOCK_HPP
|
||||||
|
#define GX_FONT_TEXT_BLOCK_HPP
|
||||||
|
|
||||||
|
#include "gx/font/Types.hpp"
|
||||||
|
#include <common/Handle.hpp>
|
||||||
|
#include <storm/Hash.hpp>
|
||||||
|
#include <tempest/Vector.hpp>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define FONT_OUTLINE 0x1
|
||||||
|
#define FONT_MONOCHROME 0x2
|
||||||
|
#define FONT_THICKOUTLINE 0x4
|
||||||
|
|
||||||
|
class CGxFont;
|
||||||
|
class CGxString;
|
||||||
|
|
||||||
|
class FONTHASHOBJ : public CHandleObject, public TSHashObject<FONTHASHOBJ, HASHKEY_STR> {
|
||||||
|
public:
|
||||||
|
CGxFont* font = nullptr;
|
||||||
|
virtual ~FONTHASHOBJ();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TEXTBLOCK : public CHandleObject {
|
||||||
|
public:
|
||||||
|
CGxString* string = nullptr;
|
||||||
|
virtual ~TEXTBLOCK();
|
||||||
|
};
|
||||||
|
|
||||||
|
void TextBlockAddShadow(HTEXTBLOCK, CImVector, const C2Vector&);
|
||||||
|
|
||||||
|
HTEXTBLOCK TextBlockCreate(HTEXTFONT fontHandle, const char* text, const CImVector& color, const C3Vector& position, float fontHeight, float blockWidth, float blockHeight, uint32_t flags, float charSpacing, float lineSpacing, float scale);
|
||||||
|
|
||||||
|
HTEXTFONT TextBlockGenerateFont(const char*, uint32_t, float);
|
||||||
|
|
||||||
|
uint32_t TextBlockGetFontFlags(HTEXTFONT);
|
||||||
|
|
||||||
|
const char* TextBlockGetFontName(HTEXTFONT);
|
||||||
|
|
||||||
|
CGxFont* TextBlockGetFontPtr(HTEXTFONT);
|
||||||
|
|
||||||
|
uint32_t TextBlockGetMaxCharsWithinWidth(HTEXTFONT, const char*, float, float, uint32_t, float*, float, float, float, uint32_t);
|
||||||
|
|
||||||
|
uint32_t TextBlockGetMaxCharsWithinWidthAndHeight(HTEXTFONT, const char*, float, float, float, uint32_t, float, float, float, uint32_t);
|
||||||
|
|
||||||
|
CGxString* TextBlockGetStringPtr(HTEXTBLOCK);
|
||||||
|
|
||||||
|
void TextBlockGetTextExtent(HTEXTFONT, const char*, uint32_t, float, float*, float, float, float, uint32_t);
|
||||||
|
|
||||||
|
float TextBlockGetWrappedTextHeight(HTEXTFONT, const char*, float, float, const C2Vector&, float, float, uint32_t);
|
||||||
|
|
||||||
|
void TextBlockSetStringPos(HTEXTBLOCK stringHandle, const C3Vector& pos);
|
||||||
|
|
||||||
|
void TextBlockUpdateColor(HTEXTBLOCK, const CImVector&);
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue
Block a user