diff options
| author | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
|---|---|---|
| committer | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
| commit | b691c43c44ff180d10e7d4a9afc83b98551ff586 (patch) | |
| tree | 3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.Client/Xbox/Font/XUI_FontData.cpp | |
| parent | def8cb415354ac390b7e89052a50605285f1aca9 (diff) | |
Initial commit
Diffstat (limited to 'Minecraft.Client/Xbox/Font/XUI_FontData.cpp')
| -rw-r--r-- | Minecraft.Client/Xbox/Font/XUI_FontData.cpp | 395 |
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 |
