aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Xbox/Font/XUI_FontData.cpp
diff options
context:
space:
mode:
authordaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
committerdaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
commitb691c43c44ff180d10e7d4a9afc83b98551ff586 (patch)
tree3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.Client/Xbox/Font/XUI_FontData.cpp
parentdef8cb415354ac390b7e89052a50605285f1aca9 (diff)
Initial commit
Diffstat (limited to 'Minecraft.Client/Xbox/Font/XUI_FontData.cpp')
-rw-r--r--Minecraft.Client/Xbox/Font/XUI_FontData.cpp395
1 files changed, 395 insertions, 0 deletions
diff --git a/Minecraft.Client/Xbox/Font/XUI_FontData.cpp b/Minecraft.Client/Xbox/Font/XUI_FontData.cpp
new file mode 100644
index 00000000..7a70cdfb
--- /dev/null
+++ b/Minecraft.Client/Xbox/Font/XUI_FontData.cpp
@@ -0,0 +1,395 @@
+#include "stdafx.h"
+#include "..\..\stubs.h"
+#include "..\..\Minecraft.h"
+#include "..\..\Textures.h"
+#include "XUI_FontData.h"
+#include "..\..\..\Minecraft.World\StringHelpers.h"
+
+
+#define USE_NEW 0
+
+
+extern IDirect3DDevice9 *g_pD3DDevice;
+
+int XUI_FontData::getMaxGlyph()
+{
+ return m_fontData->getFontData()->m_uiGlyphCount;
+}
+
+float XUI_FontData::getFontHeight()
+{
+ return m_fontData->getFontData()->m_uiGlyphHeight;
+}
+
+float XUI_FontData::getFontTopPadding()
+{
+ return 0;
+}
+
+float XUI_FontData::getFontBottomPadding()
+{
+ return 0;
+}
+
+float XUI_FontData::getFontYAdvance()
+{
+ return m_fontData->getFontData()->m_uiGlyphHeight - 1;
+}
+
+float XUI_FontData::getFontMaxWidth()
+{
+ return m_fontData->getFontData()->m_uiGlyphWidth;
+}
+
+float XUI_FontData::getMaxDescent()
+{
+ return 0;
+}
+
+float XUI_FontData::getMaxAscent()
+{
+ return m_fontData->getFontData()->m_uiGlyphHeight;
+}
+
+int XUI_FontData::getImageWidth()
+{
+ return m_fontData->getFontData()->m_uiGlyphMapX;
+}
+
+int XUI_FontData::getImageHeight()
+{
+ return m_fontData->getFontData()->m_uiGlyphMapY;
+}
+
+float XUI_FontData::SChar::getMinX()
+{
+ return 0.0f;
+}
+
+float XUI_FontData::SChar::getMaxX()
+{
+ return (float) m_parent->m_fontData->getFontData()->m_uiGlyphWidth;
+}
+
+float XUI_FontData::SChar::getMinY()
+{
+ return 0.0f;
+}
+
+float XUI_FontData::SChar::getMaxY()
+{
+ return 0.0f; //m_parent->m_fontData->getFontData()->m_uiGlyphHeight;
+}
+
+float XUI_FontData::SChar::getAdvance()
+{
+ return (float) m_parent->m_fontData->getWidth(m_glyphId);
+}
+
+int XUI_FontData::SChar::getGlyphId()
+{
+ return m_glyphId;
+}
+
+#define USE_NEW_UV 1
+
+int XUI_FontData::SChar::tu1()
+{
+#if USE_NEW_UV
+ int row = 0, col = 0;
+ m_parent->m_fontData->getPos(m_glyphId, row, col);
+ return col * m_parent->m_fontData->getFontData()->m_uiGlyphWidth;
+#else
+ return m_parent->m_Glyphs[m_glyphId].tu1;
+#endif
+}
+
+int XUI_FontData::SChar::tu2()
+{
+#if USE_NEW_UV
+ return tu1() + m_parent->m_fontData->getFontData()->m_uiGlyphWidth;
+#else
+ return m_parent->m_Glyphs[m_glyphId].tu2;
+#endif
+}
+
+int XUI_FontData::SChar::tv1()
+{
+#if USE_NEW_UV
+ int row = 0, col = 0;
+ m_parent->m_fontData->getPos(m_glyphId, row, col);
+ return row * m_parent->m_fontData->getFontData()->m_uiGlyphHeight + 1;
+#else
+ return m_parent->m_Glyphs[m_glyphId].tv1;
+#endif
+}
+
+int XUI_FontData::SChar::tv2()
+{
+#if USE_NEW_UV
+ return tv1() + m_parent->m_fontData->getFontData()->m_uiGlyphHeight;
+#else
+ return m_parent->m_Glyphs[m_glyphId].tv2;
+#endif
+}
+
+short XUI_FontData::SChar::getOffset()
+{
+ return 0;
+}
+
+short XUI_FontData::SChar::getWAdvance()
+{
+ return 0;
+}
+
+XUI_FontData::SChar XUI_FontData::getChar(const wchar_t strChar)
+{
+ SChar out;
+ out.m_glyphId = m_fontData->getGlyphId((unsigned int) strChar);
+ out.m_parent = this;
+ return out;
+}
+
+//--------------------------------------------------------------------------------------
+// Name: XUI_FontData()
+// Desc: Constructor
+//--------------------------------------------------------------------------------------
+XUI_FontData::XUI_FontData()
+{
+ m_pFontTexture = NULL;
+ m_iFontTexture = -1;
+
+ m_dwNumGlyphs = 0L;
+ m_Glyphs = NULL;
+
+ m_cMaxGlyph = 0;
+
+ m_dwNestedBeginCount = 0L;
+}
+
+
+//--------------------------------------------------------------------------------------
+// Name: ~XUI_FontData()
+// Desc: Destructor
+//--------------------------------------------------------------------------------------
+XUI_FontData::~XUI_FontData()
+{
+ Destroy();
+}
+
+
+//--------------------------------------------------------------------------------------
+// Name: Create()
+// Desc: Create the font's internal objects (texture and array of glyph info)
+// using the XPR packed resource file
+//--------------------------------------------------------------------------------------
+HRESULT XUI_FontData::Create( SFontData &sfontdata )
+{
+#ifndef _CONTENT_PACKAGE
+ app.DebugPrintf("Attempting to load font data for font: '%s'\n", sfontdata.m_strFontName.c_str());
+#endif
+
+ BufferedImage *img = new BufferedImage(sfontdata.m_wstrFilename, false, true);
+
+ m_iFontTexture = Minecraft::GetInstance()->textures->getTexture(img, C4JRender::TEXTURE_FORMAT_RxGyBzAw, false);
+
+ int imgWidth = img->getWidth(), imgHeight = img->getHeight();
+ intArray rawPixels(imgWidth * imgHeight);
+ img->getRGB(0, 0, imgWidth, imgHeight, rawPixels, 0, imgWidth);
+ delete img;
+
+ m_fontData = new CFontData( sfontdata, rawPixels.data );
+
+ if (rawPixels.data != NULL) delete [] rawPixels.data;
+
+#if 0
+ { // 4J-JEV: Load in FontData (ABC) file, and initialize member variables from it.
+
+ const ULONG_PTR c_ModuleHandle = (ULONG_PTR)GetModuleHandle(NULL);
+
+ //wsprintfW(szResourceLocator,L"section://%X,%s#%s",c_ModuleHandle,L"media", L"media/font/Mojangles_10.abc");
+ wsprintfW(szResourceLocator,L"section://%X,%s#%s%s%s",c_ModuleHandle,L"media", L"media/font/",strFontFileName.c_str(),L".abc");
+
+ BYTE *buffer;
+ UINT bufferSize;
+ hr = XuiResourceLoadAllNoLoc(
+ szResourceLocator,
+ &buffer,
+ &bufferSize
+ );
+ if( FAILED(hr) ) app.FatalLoadError();
+
+ //return Create( tex, buffer );
+ hr = Create( m_iFontTexture, buffer );
+ XuiFree(buffer);
+ }
+
+ // The ABC's are wrong, so recalc
+ // TODO 4J Stu - This isn't going to change every time we run the app, so really the FontMaker tool needs
+ // changed, or at the very least the .abc files need pre-processed to store the values we want
+ int rowV = 0;
+ int rowXOffset = 0;
+
+
+ for (unsigned int i = 0; i < 299; i++)
+ {
+ // Translate unprintable characters
+ GLYPH_ATTR* pGlyph;
+
+ DWORD letter = m_fontData->getGlyphId(i);
+ if( letter == 0 || letter >= 280 ) continue;
+ pGlyph = (GLYPH_ATTR*)&m_Glyphs[letter]; // Get the requested glyph
+
+ // 4J Stu - The original ABC's were generated for a font height that is 1 pixel higher than our cleaned up version
+ // We adjust for 1 pixel padding in the y at the top of each box.
+ pGlyph->tv1++;
+
+ if( pGlyph->tv1 != rowV )
+ {
+ rowV = pGlyph->tv1;
+ rowXOffset = 0;
+ }
+ if( pGlyph->wOffset > 0 )
+ {
+ rowXOffset += pGlyph->wOffset;
+ pGlyph->wOffset = 0;
+ }
+
+ pGlyph->tu1 -= rowXOffset;
+ pGlyph->tu2 -= rowXOffset;
+
+ int x = pGlyph->tu2-1;
+ int emptyColumnX = x;
+ for (; x >= pGlyph->tu1; x--)
+ {
+ bool emptyColumn = true;
+ for (int y = pGlyph->tv1; y < pGlyph->tv2; y++)
+ {
+ int rawPix = rawPixels[x + (y*imgWidth)];
+ DWORD pixel = rawPixels[x + (y*imgWidth)] & 0xff000000;
+ if (pixel > 0) emptyColumn = false;
+ }
+
+ if (!emptyColumn && emptyColumnX == pGlyph->tu2-1)
+ {
+ emptyColumnX = x;
+ }
+ }
+ if(emptyColumnX != pGlyph->tu2-1)
+ {
+ pGlyph->wWidth = emptyColumnX-pGlyph->tu1;
+ pGlyph->wAdvance = pGlyph->wWidth + 1;
+ }
+ }
+#endif
+
+ return S_OK;
+}
+
+
+//--------------------------------------------------------------------------------------
+// Name: Create()
+// Desc: Create the font's internal objects (texture and array of glyph info)
+//--------------------------------------------------------------------------------------
+//HRESULT XUI_FontData::Create( D3DTexture* pFontTexture, const VOID* pFontData )
+HRESULT XUI_FontData::Create( int iFontTexture, const VOID* pFontData )
+{
+ // Save a copy of the texture
+ //m_pFontTexture = pFontTexture;
+#if 0
+ m_iFontTexture = iFontTexture;
+
+ // Check version of file (to make sure it matches up with the FontMaker tool)
+ const BYTE* pData = static_cast<const BYTE*>(pFontData);
+ DWORD dwFileVersion = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_dwFileVersion;
+
+ if( dwFileVersion == ATGFONTFILEVERSION )
+ {
+ //m_fFontHeight = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_fFontHeight;
+ //m_fFontTopPadding = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_fFontTopPadding;
+ //m_fFontBottomPadding = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_fFontBottomPadding;
+ //m_fFontYAdvance = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_fFontYAdvance;
+
+ // Point to the translator string which immediately follows the 4 floats
+ m_cMaxGlyph = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_cMaxGlyph;
+
+ WCHAR* translatorTable = const_cast<FontFileHeaderImage_t*>(reinterpret_cast<const FontFileHeaderImage_t *>(pData))->m_TranslatorTable;
+
+ // 4J Stu - This map saves us some memory because the translatorTable is largely empty
+ // If we were ever to use >50% of the table then we should store it and use directly rather than the map
+ for( unsigned short i = 0; i < m_cMaxGlyph + 1; ++i )
+ {
+ if( translatorTable[i] == 0 ) continue;
+ m_TranslatorMap.insert( unordered_map<wchar_t, unsigned short>::value_type(i, translatorTable[i]) );
+ }
+
+ pData += ATGCALCFONTFILEHEADERSIZE( m_cMaxGlyph + 1 );
+
+ // Read the glyph attributes from the file
+ m_dwNumGlyphs = reinterpret_cast<const FontFileStrikesImage_t *>(pData)->m_dwNumGlyphs;
+ m_Glyphs = new GLYPH_ATTR[m_dwNumGlyphs];
+ memcpy(m_Glyphs, reinterpret_cast<const FontFileStrikesImage_t *>(pData)->m_Glyphs, sizeof(GLYPH_ATTR) * m_dwNumGlyphs);
+
+ //m_dwNumGlyphs = m_fontData->getFontData()->m_uiGlyphCount;
+ }
+ else
+ {
+ app.DebugPrintf( "Incorrect version number on font file!\n" );
+ return E_FAIL;
+ }
+#endif
+ return S_OK;
+}
+
+
+//--------------------------------------------------------------------------------------
+// Name: Destroy()
+// Desc: Destroy the font object
+//--------------------------------------------------------------------------------------
+VOID XUI_FontData::Destroy()
+{
+ if(m_pFontTexture!=NULL)
+ {
+ m_pFontTexture->Release();
+ delete m_pFontTexture;
+ }
+
+ m_fontData->release();
+
+ m_pFontTexture = NULL;
+ m_dwNumGlyphs = 0L;
+ m_cMaxGlyph = 0;
+
+ m_dwNestedBeginCount = 0L;
+}
+
+/*
+FLOAT XUI_FontData::GetCharAdvance( const WCHAR* strChar )
+{
+ unsigned int uiChar = (unsigned int) *strChar;
+ return 0.0f;// m_fontData.getAdvance(m_fontData.getGlyphId(uiChar));
+}
+
+FLOAT XUI_FontData::GetCharWidth( const WCHAR* strChar )
+{
+ return 0.0f;
+}
+
+void XUI_FontData::GetCharMetrics( const WCHAR* strChar, XUICharMetrics *xuiMetrics)
+{
+ unsigned int uiChar = (unsigned int) *strChar;
+ unsigned short usGlyph = m_fontData->getGlyphId(uiChar);
+
+ xuiMetrics->fAdvance = m_fontData->getWidth(usGlyph); //.getAdvance(usGlyph) * (float) m_fontData.getFontData()->m_uiGlyphHeight;
+ xuiMetrics->fMaxX = (float) m_fontData->getFontData()->m_uiGlyphWidth;
+ xuiMetrics->fMinX = 0.0f;
+ xuiMetrics->fMaxY = 0;// m_fontData.getFontData()->m_fAscent * (float) m_fontData.getFontData()->m_uiGlyphHeight;
+ xuiMetrics->fMinY = 0;//m_fontData.getFontData()->m_fDescent * (float) m_fontData.getFontData()->m_uiGlyphHeight;
+}
+
+unsigned short XUI_FontData::getGlyphId(wchar_t character)
+ {
+ return m_fontData->getGlyphId( (unsigned int) character );
+}
+*/ \ No newline at end of file