aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Xbox/Font/XUI_FontRenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.Client/Xbox/Font/XUI_FontRenderer.cpp')
-rw-r--r--Minecraft.Client/Xbox/Font/XUI_FontRenderer.cpp307
1 files changed, 307 insertions, 0 deletions
diff --git a/Minecraft.Client/Xbox/Font/XUI_FontRenderer.cpp b/Minecraft.Client/Xbox/Font/XUI_FontRenderer.cpp
new file mode 100644
index 00000000..48581905
--- /dev/null
+++ b/Minecraft.Client/Xbox/Font/XUI_FontRenderer.cpp
@@ -0,0 +1,307 @@
+#include "stdafx.h"
+#include "XUI_FontRenderer.h"
+#include "XUI_Font.h"
+#include "XUI_FontData.h"
+#include "..\..\..\Minecraft.World\StringHelpers.h"
+
+extern IDirect3DDevice9 *g_pD3DDevice;
+extern void GetRenderAndSamplerStates(IDirect3DDevice9 *pDevice,DWORD *RenderStateA,DWORD *SamplerStateA);
+extern void SetRenderAndSamplerStates(IDirect3DDevice9 *pDevice,DWORD *RenderStateA,DWORD *SamplerStateA);
+
+XUI_FontRenderer::XUI_FontRenderer()
+{
+ ZeroMemory(m_loadedFontData, sizeof(XUI_FontData*) * eFontData_MAX);
+
+ //XuiFontSetRenderer(this);
+
+ //Minecraft *pMinecraft=Minecraft::GetInstance();
+
+ //ScreenSizeCalculator ssc(pMinecraft->options, pMinecraft->width_phys, pMinecraft->height_phys);
+ //m_fScreenWidth=(float)pMinecraft->width_phys;
+ //m_fRawWidth=(float)ssc.rawWidth;
+ //m_fScreenHeight=(float)pMinecraft->height_phys;
+ //m_fRawHeight=(float)ssc.rawHeight;
+}
+
+HRESULT XUI_FontRenderer::Init( float fDpi )
+{
+ return( S_OK );
+
+}
+
+VOID XUI_FontRenderer::Term()
+{
+ return;
+}
+
+HRESULT XUI_FontRenderer::GetCaps( DWORD * pdwCaps )
+{
+ if( pdwCaps != NULL )
+ {
+ // setting this means XUI calls the DrawCharsToDevice method
+ *pdwCaps = XUI_FONT_RENDERER_CAP_INTERNAL_GLYPH_CACHE | XUI_FONT_RENDERER_CAP_POINT_SIZE_RESPECTED | XUI_FONT_RENDERER_STYLE_DROPSHADOW;
+ }
+ return ( S_OK );
+}
+
+HRESULT XUI_FontRenderer::CreateFont( const TypefaceDescriptor * pTypefaceDescriptor, float fPointSize, DWORD dwStyle, DWORD dwReserved, HFONTOBJ * phFont )
+{
+ float fXuiSize = fPointSize * ( 16.0f / 14.0f );
+ //float fXuiSize = fPointSize * ( 16.0f / 16.0f );
+ fXuiSize /= 4.0f;
+ fXuiSize = floor( fXuiSize );
+ int xuiSize = (int)(fXuiSize * 4.0f);
+ if( xuiSize < 1 ) xuiSize = 8;
+
+ // 4J Stu - We have fonts based on multiples of 8 or 12
+ // We don't want to make the text larger as then it may not fit in the box specified
+ // so we decrease the size until we find one that will look ok
+ while( xuiSize%8!=0 && xuiSize%12!=0 ) xuiSize -= 2;
+
+ //app.DebugPrintf("point size is: %f, xuiSize is: %d\n", fPointSize, xuiSize);
+
+ XUI_Font *font = NULL;
+ XUI_FontData *fontData = NULL;
+ FLOAT scale = 1;
+
+ eFontData efontdata;
+ if( xuiSize%12==0 )
+ {
+ scale = xuiSize/12;
+ efontdata = eFontData_Mojangles_11;
+ }
+ else
+ {
+ scale = xuiSize/8;
+ efontdata = eFontData_Mojangles_7;
+ }
+
+ font = m_loadedFonts[efontdata][scale];
+ if (font == NULL)
+ {
+ fontData = m_loadedFontData[efontdata];
+ if (fontData == NULL)
+ {
+ SFontData *sfontdata;
+ switch (efontdata)
+ {
+ case eFontData_Mojangles_7: sfontdata = &SFontData::Mojangles_7; break;
+ case eFontData_Mojangles_11: sfontdata = &SFontData::Mojangles_11; break;
+ default: sfontdata = NULL; break;
+ }
+
+ fontData = new XUI_FontData();
+ fontData->Create(*sfontdata);
+
+ m_loadedFontData[efontdata] = fontData;
+ }
+
+ font = new XUI_Font( efontdata, scale, fontData );
+ m_loadedFonts[efontdata][scale] = font;
+ }
+ font->IncRefCount();
+
+ *phFont = (HFONTOBJ)font;
+ return S_OK;
+}
+
+VOID XUI_FontRenderer::ReleaseFont( HFONTOBJ hFont )
+{
+ XUI_Font *xuiFont = (XUI_Font*) hFont;
+ if (xuiFont != NULL)
+ {
+ xuiFont->DecRefCount();
+ if (xuiFont->refCount <= 0)
+ {
+ AUTO_VAR(it, m_loadedFonts[xuiFont->m_iFontData].find(xuiFont->m_fScaleFactor) );
+ if (it != m_loadedFonts[xuiFont->m_iFontData].end()) m_loadedFonts[xuiFont->m_iFontData].erase(it);
+ delete hFont;
+ }
+ }
+ return;
+}
+
+HRESULT XUI_FontRenderer::GetFontMetrics( HFONTOBJ hFont, XUIFontMetrics *pFontMetrics )
+{
+ if( hFont == 0 || pFontMetrics == 0 ) return E_INVALIDARG;
+
+ XUI_Font *font = (XUI_Font *)hFont;
+
+ pFontMetrics->fLineHeight = (font->m_fontData->getFontYAdvance() + 1) * font->m_fYScaleFactor;
+ pFontMetrics->fMaxAscent = font->m_fontData->getMaxAscent() * font->m_fYScaleFactor;
+ pFontMetrics->fMaxDescent = font->m_fontData->getMaxDescent() * font->m_fYScaleFactor;
+ pFontMetrics->fMaxHeight = font->m_fontData->getFontHeight() * font->m_fYScaleFactor;
+ pFontMetrics->fMaxWidth = font->m_fontData->getFontMaxWidth() * font->m_fXScaleFactor;
+ pFontMetrics->fMaxAdvance = font->m_fontData->getFontMaxWidth() * font->m_fXScaleFactor;
+
+ //*pFontMetrics = font->m_fontMetrics; // g_fontMetrics;
+ return( S_OK );
+}
+
+HRESULT XUI_FontRenderer::GetCharMetrics( HFONTOBJ hFont, WCHAR wch, XUICharMetrics *pCharMetrics )
+{
+ if (hFont == 0 || pCharMetrics == 0) return E_INVALIDARG;
+
+ XUI_Font *font = (XUI_Font *)hFont;
+ XUI_FontData::SChar sChar = font->m_fontData->getChar(wch);
+
+ pCharMetrics->fMinX = sChar.getMinX() * font->m_fYScaleFactor;
+ pCharMetrics->fMinY = sChar.getMinY() * font->m_fYScaleFactor;
+ pCharMetrics->fMaxX = sChar.getMaxX() * font->m_fYScaleFactor;
+ pCharMetrics->fMaxY = sChar.getMaxY() * font->m_fYScaleFactor;
+ pCharMetrics->fAdvance = sChar.getAdvance() * font->m_fYScaleFactor;
+
+ return(S_OK);
+}
+
+HRESULT XUI_FontRenderer::DrawCharToTexture( HFONTOBJ hFont, WCHAR wch, HXUIDC hDC, IXuiTexture * pTexture, UINT x, UINT y, UINT width, UINT height, UINT insetX, UINT insetY )
+{
+ if( hFont==0 || pTexture==NULL ) return E_INVALIDARG;
+ return( S_OK );
+}
+
+HRESULT XUI_FontRenderer::DrawCharsToDevice( HFONTOBJ hFont, CharData * pCharData, DWORD dwCount, RECT *pClipRect, HXUIDC hDC, D3DXMATRIX * pWorldViewProj )
+{
+ if( hFont == 0 ) return E_INVALIDARG;
+ if( dwCount == 0 ) return( S_OK );
+
+ DWORD RenderStateA[8];
+ DWORD SamplerStateA[5];
+ XMVECTOR vconsts[20];
+ XMVECTOR pconsts[20];
+ XUI_Font *font = (XUI_Font *)hFont;
+
+ // 4J-PB - if we're in 480 Widescreen mode, we need to ensure that the font characters are aligned on an even boundary if they are a 2x multiple
+ if(!RenderManager.IsHiDef())
+ {
+ if(RenderManager.IsWidescreen())
+ {
+ float fScaleX, fScaleY;
+ font->GetScaleFactors(&fScaleX,&fScaleY);
+ int iScaleX=fScaleX;
+ int iScaleY=fScaleY;
+
+ if(iScaleX%2==0)
+ {
+ int iWorldX=pWorldViewProj->_41;
+ pWorldViewProj->_41 = (float)(iWorldX & -2);
+ }
+ if(iScaleY%2==0)
+ {
+ int iWorldY=pWorldViewProj->_42;
+ pWorldViewProj->_42 = (float)(iWorldY & -2);
+ }
+ }
+ else
+ {
+ // make x an even number for 480 4:3
+ int iWorldX=pWorldViewProj->_41;
+ pWorldViewProj->_41 = (float)(iWorldX & -2);
+
+ // 480 SD mode - y needs to be on a pixel boundary when multiplied by 1.5, so if it's an odd number, subtract 1/3 from it
+ int iWorldY=pWorldViewProj->_42;
+ if(iWorldY%2==1)
+ {
+ pWorldViewProj->_42-=1.0f/3.0f;
+ }
+ }
+ }
+
+ g_pD3DDevice->GetVertexShaderConstantF( 0, (float *)vconsts, 20 );
+ g_pD3DDevice->GetPixelShaderConstantF( 0, (float *)pconsts, 20 );
+ g_pD3DDevice->SetRenderState(D3DRS_HALFPIXELOFFSET, TRUE);
+ GetRenderAndSamplerStates(g_pD3DDevice, RenderStateA, SamplerStateA );
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+
+ RenderManager.Set_matrixDirty();
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, 1280.0f, 720.0f, 0, 1000, 3000);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, -2000);
+ glColor4f(1.0f,1.0f,1.0f,1.0f);
+ float matrixCopy[16];
+ memcpy(matrixCopy, pWorldViewProj, 64);
+ matrixCopy[11] = 0.0f;
+ matrixCopy[12] = floor(matrixCopy[12] + 0.5f);
+ matrixCopy[13] = floor(matrixCopy[13] + 0.5f);
+ matrixCopy[14] = floor(matrixCopy[14] + 0.5f);
+ matrixCopy[15] = 1.0f;
+ glMultMatrixf(matrixCopy);
+
+
+ float lineXPos = 0.0f;
+ float lineYPos = 0.0f;
+ DWORD colour = 0;
+ DWORD style = 0;
+#if 1
+ for( int i = 0; i < dwCount; i++ )
+ {
+ wstring string;
+ string.push_back(pCharData[i].wch);
+ lineYPos = pCharData[i].y;
+ lineXPos = pCharData[i].x;
+ colour = pCharData[i].dwColor;
+ style = pCharData[i].dwStyle;
+
+ //if(pCharData[i].wch > font->m_fontData->getMaxGlyph())
+ if ( !font->m_fontData->getChar(pCharData[i].wch).hasChar() )
+ {
+ // Can't render this character, fallback to the default renderer
+ app.OverrideFontRenderer(false,false);
+ break;
+ }
+#else
+ DWORD i = 0;
+ while( i < dwCount )
+ {
+ wstring string;
+ lineYPos = pCharData[i].y;
+ lineXPos = pCharData[i].x;
+ colour = pCharData[i].dwColor;
+ style = pCharData[i].dwStyle;
+
+ while(i < dwCount && pCharData[i].y == lineYPos)
+ {
+ string.push_back(pCharData[i].wch);
+ ++i;
+ }
+#endif
+
+ bool dropShadow = false;
+ if( (style & XUI_FONT_STYLE_DROPSHADOW) == XUI_FONT_STYLE_DROPSHADOW) dropShadow = true;
+
+ //int yPos = (int)pCharData[i].y + (int)(font->m_fontMetrics.fLineHeight - font->m_fontMetrics.fMaxAscent)/2;
+ //if( (pCharData[i].dwStyle & XUI_FONT_STYLE_VERTICAL_CENTER) == XUI_FONT_STYLE_VERTICAL_CENTER)
+ //{
+ // yPos = (pClipRect->bottom - (int)font->m_fontMetrics.fLineHeight) / 2;
+ //}
+
+ if(dropShadow)
+ {
+ DWORD shadowColour;
+ XuiGetTextDropShadowColor(hDC, &shadowColour);
+ // 4J Stu - Shadow colour is currently ignored
+ font->DrawShadowText( lineXPos,lineYPos,colour,shadowColour,string.c_str() );
+ //drawShadow(thisChar, (int)pCharData[i].x, yPos, pCharData[i].dwColor );
+ }
+ else
+ {
+ font->DrawText( lineXPos,lineYPos,colour,string.c_str() );
+ //draw(thisChar, (int)pCharData[i].x, yPos, pCharData[i].dwColor, false );
+ }
+ }
+
+ g_pD3DDevice->SetVertexShaderConstantF( 0, (float *)vconsts, 20 );
+ g_pD3DDevice->SetPixelShaderConstantF( 0, (float *)pconsts, 20 );
+ SetRenderAndSamplerStates(g_pD3DDevice, RenderStateA, SamplerStateA );
+ g_pD3DDevice->SetRenderState(D3DRS_HALFPIXELOFFSET, FALSE);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+
+ XuiRenderRestoreState(hDC);
+
+ return( S_OK );
+}