diff --git a/.gitmodules b/.gitmodules index 80f6b447..f275c17e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "mainui"] path = mainui url = https://github.com/FWGS/mainui_cpp -[submodule "vgui_support/miniutl"] - path = vgui_support/miniutl - url = https://github.com/FWGS/miniutl diff --git a/engine/client/vgui/vgui_main.h b/engine/client/vgui/vgui_main.h deleted file mode 100644 index 0fe2857c..00000000 --- a/engine/client/vgui/vgui_main.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -vgui_main.h - vgui main header -Copyright (C) 2011 Uncle Mike - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -*/ - -#ifndef VGUI_MAIN_H -#define VGUI_MAIN_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace vgui; - -struct PaintStack -{ - Panel *m_pPanel; - int iTranslateX; - int iTranslateY; - int iScissorLeft; - int iScissorRight; - int iScissorTop; - int iScissorBottom; -}; - -class CEngineSurface : public SurfaceBase -{ -private: - void InitVertex( vpoint_t &vertex, int x, int y, float u, float v ); -public: - CEngineSurface( Panel *embeddedPanel ); - ~CEngineSurface(); -public: - // not used in engine instance - virtual bool setFullscreenMode( int wide, int tall, int bpp ) { return false; } - virtual void setWindowedMode( void ) { } - virtual void setTitle( const char *title ) { } - virtual void createPopup( Panel* embeddedPanel ) { } - virtual bool isWithin( int x, int y ) { return true; } - void SetupPaintState( const PaintStack *paintState ); -#ifdef NEW_VGUI_DLL - virtual void GetMousePos( int &x, int &y ) { } -#endif - virtual bool hasFocus( void ) { return true; } -protected: - virtual int createNewTextureID( void ); - virtual void drawSetColor( int r, int g, int b, int a ); - virtual void drawSetTextColor( int r, int g, int b, int a ); - virtual void drawFilledRect( int x0, int y0, int x1, int y1 ); - virtual void drawOutlinedRect( int x0,int y0,int x1,int y1 ); - virtual void drawSetTextFont( Font *font ); - virtual void drawSetTextPos( int x, int y ); - virtual void drawPrintText( const char* text, int textLen ); - virtual void drawSetTextureRGBA( int id, const char* rgba, int wide, int tall ); - virtual void drawSetTexture( int id ); - virtual void drawTexturedRect( int x0, int y0, int x1, int y1 ); - virtual void drawPrintChar( int x, int y, int wide, int tall, float s0, float t0, float s1, float t1, int color[4] ); - virtual void addCharToBuffer( const vpoint_t *ul, const vpoint_t *lr, int color[4] ); - virtual void setCursor( Cursor* cursor ); - virtual void pushMakeCurrent( Panel* panel, bool useInsets ); - virtual void popMakeCurrent( Panel* panel ); - // not used in engine instance - virtual bool createPlat( void ) { return false; } - virtual bool recreateContext( void ) { return false; } - virtual void enableMouseCapture( bool state ) { } - virtual void invalidate( Panel *panel ) { } - virtual void setAsTopMost( bool state ) { } - virtual void applyChanges( void ) { } - virtual void swapBuffers( void ) { } - virtual void flushBuffer( void ); -protected: - int _drawTextPos[2]; - int _drawColor[4]; - int _drawTextColor[4]; - int _translateX, _translateY; - int _currentTexture; - Panel *currentPanel; -}; - -// initialize VGUI::App as external (part of engine) -class CEngineApp : public App -{ -public: - virtual void main( int argc, char* argv[] ) { } - virtual void setCursorPos( int x, int y ); // we need to recompute abs position to window - virtual void getCursorPos( int &x,int &y ); -protected: - virtual void platTick(void) { } -}; - -extern Panel *rootPanel; -extern CEngineSurface *engSurface; -extern CEngineApp *engApp; - -// -// vgui_input.cpp -// -void VGUI_InitCursors( void ); -void VGUI_CursorSelect( Cursor *cursor ); -void VGUI_ActivateCurrentCursor( void ); - -#endif//VGUI_MAIN_H \ No newline at end of file diff --git a/vgui_support/vgui_clip.cpp b/vgui_support/vgui_clip.cpp index ea30e771..67085577 100644 --- a/vgui_support/vgui_clip.cpp +++ b/vgui_support/vgui_clip.cpp @@ -43,8 +43,8 @@ void EnableScissor( qboolean enable ) void SetScissorRect( int left, int top, int right, int bottom ) { // Check for a valid rectangle... - Assert( left <= right ); - Assert( top <= bottom ); + assert( left <= right ); + assert( top <= bottom ); g_ScissorRect.left = left; g_ScissorRect.top = top; @@ -121,4 +121,4 @@ qboolean ClipRect( const vpoint_t &inUL, const vpoint_t &inLR, vpoint_t *pOutUL, } return true; } -} \ No newline at end of file +} diff --git a/vgui_support/vgui_font.cpp b/vgui_support/vgui_font.cpp deleted file mode 100644 index 99369508..00000000 --- a/vgui_support/vgui_font.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* -vgui_font.cpp - fonts management -Copyright (C) 2011 Uncle Mike - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -In addition, as a special exception, the author gives permission -to link the code of this program with VGUI library developed by -Valve, L.L.C ("Valve"). You must obey the GNU General Public License -in all respects for all of the code used other than VGUI library. -If you modify this file, you may extend this exception to your -version of the file, but you are not obligated to do so. If -you do not wish to do so, delete this exception statement -from your version. - -*/ - -#include "vgui_main.h" - -int FontCache::s_pFontPageSize[FONT_PAGE_SIZE_COUNT] = { 16, 32, 64, 128 }; - -FontCache::FontCache() : m_CharCache( 0, 256, CacheEntryLessFunc ) -{ - CacheEntry_t listHead = { 0, 0 }; - - m_LRUListHeadIndex = m_CharCache.Insert( listHead ); - m_CharCache[m_LRUListHeadIndex].nextEntry = m_LRUListHeadIndex; - m_CharCache[m_LRUListHeadIndex].prevEntry = m_LRUListHeadIndex; - for( int i = 0; i < FONT_PAGE_SIZE_COUNT; i++ ) - { - m_pCurrPage[i] = -1; - } -} - -bool FontCache::CacheEntryLessFunc( CacheEntry_t const &lhs, CacheEntry_t const &rhs ) -{ - if( lhs.font < rhs.font ) - return true; - else if( lhs.font > rhs.font ) - return false; - - return ( lhs.ch < rhs.ch ); -} - -bool FontCache::GetTextureForChar( Font *font, char ch, int *textureID, float **texCoords ) -{ - static CacheEntry_t cacheitem; - - cacheitem.font = font; - cacheitem.ch = ch; - - Assert( texCoords != NULL ); - - *texCoords = cacheitem.texCoords; - - HCacheEntry cacheHandle = m_CharCache.Find( cacheitem ); - - if( cacheHandle != 65535 && m_CharCache.IsValidIndex( cacheHandle )) - { - // we have an entry already, return that - int page = m_CharCache[cacheHandle].page; - *textureID = m_PageList[page].textureID; - //else return false; - *texCoords = m_CharCache[cacheHandle].texCoords; - return true; - } - - // get the char details - int fontTall = font->getTall(); - int a, b, c; - font->getCharABCwide( (byte)ch, a, b, c ); - int fontWide = b; - - // get a texture to render into - int page, drawX, drawY, twide, ttall; - if( !AllocatePageForChar( fontWide, fontTall, page, drawX, drawY, twide, ttall )) - return false; - - // create a buffer and render the character into it - int nByteCount = s_pFontPageSize[FONT_PAGE_SIZE_COUNT-1] * s_pFontPageSize[FONT_PAGE_SIZE_COUNT-1] * 4; - byte * rgba = (byte *)g_api->EngineMalloc(nByteCount);//(byte *)Z_Malloc( nByteCount ); - font->getCharRGBA( (byte)ch, 0, 0, fontWide, fontTall, rgba ); - - // upload the new sub texture - g_api->BindTexture( m_PageList[page].textureID ); - g_api->UploadTextureBlock( m_PageList[page].textureID, drawX, drawY, rgba, fontWide, fontTall ); - - // set the cache info - cacheitem.page = page; - - cacheitem.texCoords[0] = (float)((double)drawX / ((double)twide)); - cacheitem.texCoords[1] = (float)((double)drawY / ((double)ttall)); - cacheitem.texCoords[2] = (float)((double)(drawX + fontWide) / (double)twide); - cacheitem.texCoords[3] = (float)((double)(drawY + fontTall) / (double)ttall); - - m_CharCache.Insert( cacheitem ); - - // return the data - *textureID = m_PageList[page].textureID; - // memcpy( texCoords, cacheitem.texCoords, sizeof( float ) * 4 ); - return true; -} - -int FontCache::ComputePageType( int charTall ) const -{ - for( int i = 0; i < FONT_PAGE_SIZE_COUNT; i++ ) - { - if( charTall < s_pFontPageSize[i] ) - return i; - } - return -1; -} - -bool FontCache::AllocatePageForChar( int charWide, int charTall, int &pageIndex, int &drawX, int &drawY, int &twide, int &ttall ) -{ - // see if there is room in the last page for this character - int nPageType = ComputePageType( charTall ); - - if( nPageType < 0 ) - return false; - - pageIndex = m_pCurrPage[nPageType]; - - int nNextX = 0; - bool bNeedsNewPage = true; - - if( pageIndex > -1 ) - { - Page_t &page = m_PageList[pageIndex]; - - nNextX = page.nextX + charWide; - - // make sure we have room on the current line of the texture page - if( nNextX > page.wide ) - { - // move down a line - page.nextX = 0; - nNextX = charWide; - page.nextY += page.fontHeight + 1; - } - - bNeedsNewPage = (( page.nextY + page.fontHeight + 1 ) > page.tall ); - } - - if( bNeedsNewPage ) - { - // allocate a new page - pageIndex = m_PageList.AddToTail(); - Page_t &newPage = m_PageList[pageIndex]; - m_pCurrPage[nPageType] = pageIndex; - - newPage.textureID = g_api->GenerateTexture(); - - newPage.fontHeight = s_pFontPageSize[nPageType]; - newPage.wide = 256; - newPage.tall = 256; - newPage.nextX = 0; - newPage.nextY = 0; - - nNextX = charWide; - - // create empty texture - g_api->CreateTexture( newPage.textureID, 256, 256 ); - } - - // output the position - Page_t &page = m_PageList[pageIndex]; - drawX = page.nextX; - drawY = page.nextY; - twide = page.wide; - ttall = page.tall; - - // update the next position to draw in - page.nextX = nNextX + 1; - - return true; -} diff --git a/vgui_support/vgui_int.cpp b/vgui_support/vgui_int.cpp index 2c61df88..8d17fe8f 100644 --- a/vgui_support/vgui_int.cpp +++ b/vgui_support/vgui_int.cpp @@ -28,19 +28,12 @@ namespace vgui_support { vguiapi_t *g_api; -FontCache *g_FontCache = 0; - Panel *rootpanel = NULL; CEngineSurface *surface = NULL; CEngineApp staticApp; void VGui_Startup( int width, int height ) { - if( !g_FontCache ) - { - g_FontCache = new FontCache(); - } - if( rootpanel ) { rootpanel->setSize( width, height ); diff --git a/vgui_support/vgui_main.h b/vgui_support/vgui_main.h index 0dd39ecf..7765c862 100644 --- a/vgui_support/vgui_main.h +++ b/vgui_support/vgui_main.h @@ -31,9 +31,9 @@ from your version. #include #endif +#include + #include "vgui_api.h" -#include "utlvector.h" -#include "utlrbtree.h" #include #include @@ -51,80 +51,20 @@ extern vguiapi_t *g_api; using namespace vgui; -class FontCache +struct PaintStack { -public: - FontCache(); - ~FontCache() { } - - // returns a texture ID and a pointer to an array of 4 texture coords for the given character & font - // uploads more texture if necessary - bool GetTextureForChar( Font *font, char ch, int *textureID, float **texCoords ); -private: - // NOTE: If you change this, change s_pFontPageSize - enum - { - FONT_PAGE_SIZE_16, - FONT_PAGE_SIZE_32, - FONT_PAGE_SIZE_64, - FONT_PAGE_SIZE_128, - FONT_PAGE_SIZE_COUNT - }; - - // a single character in the cache - typedef unsigned short HCacheEntry; - struct CacheEntry_t - { - Font *font; - char ch; - byte page; - float texCoords[4]; - - HCacheEntry nextEntry; // doubly-linked list for use in the LRU - HCacheEntry prevEntry; - }; - - // a single texture page - struct Page_t - { - short textureID; - short fontHeight; - short wide, tall; // total size of the page - short nextX, nextY; // position to draw any new character positions - }; - - // allocates a new page for a given character - bool AllocatePageForChar( int charWide, int charTall, int &pageIndex, int &drawX, int &drawY, int &twide, int &ttall ); - - // Computes the page size given a character height - int ComputePageType( int charTall ) const; - - static bool CacheEntryLessFunc( const CacheEntry_t &lhs, const CacheEntry_t &rhs ); - - // cache - typedef CUtlVector FontPageList_t; - - CUtlRBTree m_CharCache; - FontPageList_t m_PageList; - int m_pCurrPage[FONT_PAGE_SIZE_COUNT]; - HCacheEntry m_LRUListHeadIndex; - - static int s_pFontPageSize[FONT_PAGE_SIZE_COUNT]; + Panel *m_pPanel; + int iTranslateX; + int iTranslateY; + int iScissorLeft; + int iScissorRight; + int iScissorTop; + int iScissorBottom; }; class CEngineSurface : public SurfaceBase { private: - struct paintState_t - { - Panel *m_pPanel; - int iTranslateX; - int iTranslateY; - int iScissorLeft; - int iScissorRight; - int iScissorTop; - int iScissorBottom; - }; // point translation for current panel int _translateX; @@ -133,9 +73,7 @@ private: // the size of the window to draw into int _surfaceExtents[4]; - CUtlVector _paintStack; - - void SetupPaintState( const paintState_t &paintState ); + void SetupPaintState( const PaintStack *paintState ); void InitVertex( vpoint_t &vertex, int x, int y, float u, float v ); public: CEngineSurface( Panel *embeddedPanel ); @@ -151,7 +89,8 @@ public: // now it's not abstract class, yay virtual void GetMousePos(int &x, int &y) { g_api->GetCursorPos(&x, &y); - } + } + void drawPrintChar(int x, int y, int wide, int tall, float s0, float t0, float s1, float t1, int color[]); protected: virtual int createNewTextureID( void ); virtual void drawSetColor( int r, int g, int b, int a ); @@ -177,7 +116,6 @@ protected: virtual void applyChanges( void ) { } virtual void swapBuffers( void ) { } protected: - Font* _hCurrentFont; Cursor* _hCurrentCursor; int _drawTextPos[2]; int _drawColor[4]; @@ -197,11 +135,7 @@ public: // // vgui_input.cpp // -void VGUI_InitCursors( void ); -void VGUI_CursorSelect( Cursor *cursor ); -void VGUI_ActivateCurrentCursor( void ); void *VGui_GetPanel( void ); -void VGui_RunFrame( void ); void VGui_Paint( void ); void VGUI_Mouse(VGUI_MouseAction action, int code); void VGUI_Key(VGUI_KeyAction action, VGUI_KeyCode code); @@ -213,9 +147,6 @@ void EnableScissor( qboolean enable ); void SetScissorRect( int left, int top, int right, int bottom ); qboolean ClipRect( const vpoint_t &inUL, const vpoint_t &inLR, vpoint_t *pOutUL, vpoint_t *pOutLR ); -extern FontCache *g_FontCache; - - extern CEngineSurface *surface; extern Panel *root; } diff --git a/vgui_support/vgui_surf.cpp b/vgui_support/vgui_surf.cpp index 8c949c08..e994021c 100644 --- a/vgui_support/vgui_surf.cpp +++ b/vgui_support/vgui_surf.cpp @@ -26,6 +26,28 @@ from your version. #include #include "vgui_main.h" +#define MAX_PAINT_STACK 16 +#define FONT_SIZE 512 +#define FONT_PAGES 8 + +struct FontInfo +{ + int id; + int pageCount; + int pageForChar[256]; + int bindIndex[FONT_PAGES]; + float texCoord[256][FONT_PAGES]; + int contextCount; +}; + +static int staticContextCount = 0; +static char staticRGBA[FONT_SIZE * FONT_SIZE * 4]; +static Font* staticFont = NULL; +static FontInfo* staticFontInfo; +static Dar staticFontInfoDar; +static PaintStack paintStack[MAX_PAINT_STACK]; +static int staticPaintStackPos = 0; + #define ColorIndex( c )((( c ) - '0' ) & 7 ) CEngineSurface :: CEngineSurface( Panel *embeddedPanel ):SurfaceBase( embeddedPanel ) @@ -39,8 +61,14 @@ CEngineSurface :: CEngineSurface( Panel *embeddedPanel ):SurfaceBase( embeddedPa //_surfaceExtents[3] = menu.globals->scrHeight; embeddedPanel->getSize(_surfaceExtents[2], _surfaceExtents[3]); _drawTextPos[0] = _drawTextPos[1] = 0; - _hCurrentFont = null; _hCurrentCursor = null; + + staticFont = NULL; + staticFontInfo = NULL; + staticFontInfoDar.setCount( 0 ); + staticPaintStackPos = 0; + staticContextCount++; + _translateX = _translateY = 0; } @@ -67,12 +95,12 @@ void CEngineSurface :: setCursor( Cursor *cursor ) g_api->CursorSelect( (VGUI_DefaultCursor)cursor->getDefaultCursor() ); } -void CEngineSurface :: SetupPaintState( const paintState_t &paintState ) +void CEngineSurface :: SetupPaintState( const PaintStack *paintState ) { - _translateX = paintState.iTranslateX; - _translateY = paintState.iTranslateY; - SetScissorRect( paintState.iScissorLeft, paintState.iScissorTop, - paintState.iScissorRight, paintState.iScissorBottom ); + _translateX = paintState->iTranslateX; + _translateY = paintState->iTranslateY; + SetScissorRect( paintState->iScissorLeft, paintState->iScissorTop, + paintState->iScissorRight, paintState->iScissorBottom ); } void CEngineSurface :: InitVertex( vpoint_t &vertex, int x, int y, float u, float v ) @@ -136,7 +164,93 @@ void CEngineSurface :: drawOutlinedRect( int x0, int y0, int x1, int y1 ) void CEngineSurface :: drawSetTextFont( Font *font ) { - _hCurrentFont = font; + staticFont = font; + + if( font ) + { + bool buildFont = false; + + staticFontInfo = NULL; + + for( int i = 0; i < staticFontInfoDar.getCount(); i++ ) + { + if( staticFontInfoDar[i]->id == font->getId( )) + { + staticFontInfo = staticFontInfoDar[i]; + if( staticFontInfo->contextCount != staticContextCount ) + buildFont = true; + } + } + + if( !staticFontInfo || buildFont ) + { + staticFontInfo = new FontInfo; + staticFontInfo->id = 0; + staticFontInfo->pageCount = 0; + staticFontInfo->bindIndex[0] = 0; + staticFontInfo->bindIndex[1] = 0; + staticFontInfo->bindIndex[2] = 0; + staticFontInfo->bindIndex[3] = 0; + memset( staticFontInfo->pageForChar, 0, sizeof( staticFontInfo->pageForChar )); + staticFontInfo->contextCount = -1; + staticFontInfo->id = staticFont->getId(); + staticFontInfoDar.putElement( staticFontInfo ); + staticFontInfo->contextCount = staticContextCount; + + int currentPage = 0; + int x = 0, y = 0; + + memset( staticRGBA, 0, sizeof( staticRGBA )); + + for( int i = 0; i < 256; i++ ) + { + int abcA, abcB, abcC; + staticFont->getCharABCwide( i, abcA, abcB, abcC ); + + int wide = abcB; + + if( isspace( i )) continue; + + int tall = staticFont->getTall(); + + if( x + wide + 1 > FONT_SIZE ) + { + x = 0; + y += tall + 1; + } + + if( y + tall + 1 > FONT_SIZE ) + { + if( !staticFontInfo->bindIndex[currentPage] ) + staticFontInfo->bindIndex[currentPage] = createNewTextureID(); + drawSetTextureRGBA( staticFontInfo->bindIndex[currentPage], staticRGBA, FONT_SIZE, FONT_SIZE ); + currentPage++; + + if( currentPage == FONT_PAGES ) + break; + + memset( staticRGBA, 0, sizeof( staticRGBA )); + x = y = 0; + } + + staticFont->getCharRGBA( i, x, y, FONT_SIZE, FONT_SIZE, (byte *)staticRGBA ); + staticFontInfo->pageForChar[i] = currentPage; + staticFontInfo->texCoord[i][0] = (float)((double)x / (double)FONT_SIZE ); + staticFontInfo->texCoord[i][1] = (float)((double)y / (double)FONT_SIZE ); + staticFontInfo->texCoord[i][2] = (float)((double)(x + wide)/(double)FONT_SIZE ); + staticFontInfo->texCoord[i][3] = (float)((double)(y + tall)/(double)FONT_SIZE ); + x += wide + 1; + } + + if( currentPage != FONT_PAGES ) + { + if( !staticFontInfo->bindIndex[currentPage] ) + staticFontInfo->bindIndex[currentPage] = createNewTextureID(); + drawSetTextureRGBA( staticFontInfo->bindIndex[currentPage], staticRGBA, FONT_SIZE, FONT_SIZE ); + } + staticFontInfo->pageCount = currentPage + 1; + } + } } void CEngineSurface :: drawSetTextPos( int x, int y ) @@ -145,19 +259,43 @@ void CEngineSurface :: drawSetTextPos( int x, int y ) _drawTextPos[1] = y; } +void CEngineSurface :: drawPrintChar( int x, int y, int wide, int tall, float s0, float t0, float s1, float t1, int color[4] ) +{ + vpoint_t ul, lr; + + ul.point[0] = x; + ul.point[1] = y; + lr.point[0] = x + wide; + lr.point[1] = y + tall; + + // gets at the texture coords for this character in its texture page + ul.coord[0] = s0; + ul.coord[1] = t0; + lr.coord[0] = s1; + lr.coord[1] = t1; + + vpoint_t clippedRect[2]; + + if( !ClipRect( ul, lr, &clippedRect[0], &clippedRect[1] )) + return; + + g_api->SetupDrawingImage( color ); + g_api->DrawQuad( &clippedRect[0], &clippedRect[1] ); // draw the letter +} + void CEngineSurface :: drawPrintText( const char* text, int textLen ) { //return; static bool hasColor = 0; static int numColor = 7; - if( !text || !_hCurrentFont || _drawTextColor[3] >= 255 ) + if( !text || !staticFont || _drawTextColor[3] >= 255 ) return; int x = _drawTextPos[0] + _translateX; int y = _drawTextPos[1] + _translateY; - int iTall = _hCurrentFont->getTall(); + int tall = staticFont->getTall(); int j, iTotalWidth = 0; int curTextColor[4]; @@ -167,9 +305,9 @@ void CEngineSurface :: drawPrintText( const char* text, int textLen ) { for( j = 0; j < 3; j++ ) // grab predefined color curTextColor[j] = g_api->GetColor(numColor,j); - } - else - { + } + else + { for( j = 0; j < 3; j++ ) // revert default color curTextColor[j] = _drawTextColor[j]; } @@ -192,55 +330,26 @@ void CEngineSurface :: drawPrintText( const char* text, int textLen ) } for( int i = 0; i < textLen; i++ ) { - char ch = g_api->ProcessUtfChar( (unsigned char)text[i] ); - if( !ch ) + int curCh = g_api->ProcessUtfChar( (unsigned char)text[i] ); + if( !curCh ) { continue; } - int abcA,abcB,abcC; - _hCurrentFont->getCharABCwide( ch, abcA, abcB, abcC ); + int abcA, abcB, abcC; + + staticFont->getCharABCwide( curCh, abcA, abcB, abcC ); + + float s0 = staticFontInfo->texCoord[curCh][0]; + float t0 = staticFontInfo->texCoord[curCh][1]; + float s1 = staticFontInfo->texCoord[curCh][2]; + float t1 = staticFontInfo->texCoord[curCh][3]; + int wide = abcB; iTotalWidth += abcA; - int iWide = abcB; - - //if( !iswspace( ch )) - { - // get the character texture from the cache - int iTexId = 0; - float *texCoords = NULL; - - if( !g_FontCache->GetTextureForChar( _hCurrentFont, ch, &iTexId, &texCoords )) - { - continue; - } - - Assert( texCoords != NULL ); - - vpoint_t ul, lr; - - ul.point[0] = x + iTotalWidth; - ul.point[1] = y; - lr.point[0] = ul.point[0] + iWide; - lr.point[1] = ul.point[1] + iTall; - - // gets at the texture coords for this character in its texture page - ul.coord[0] = texCoords[0]; - ul.coord[1] = texCoords[1]; - lr.coord[0] = texCoords[2]; - lr.coord[1] = texCoords[3]; - - vpoint_t clippedRect[2]; - - if( !ClipRect( ul, lr, &clippedRect[0], &clippedRect[1] )) - continue; - - drawSetTexture( iTexId ); - g_api->SetupDrawingText( curTextColor ); - g_api->DrawQuad( &clippedRect[0], &clippedRect[1] ); // draw the letter - } - - iTotalWidth += iWide + abcC; + drawSetTexture( staticFontInfo->bindIndex[staticFontInfo->pageForChar[curCh]] ); + drawPrintChar( x + iTotalWidth, y, wide, tall, s0, t0, s1, t1, curTextColor ); + iTotalWidth += wide + abcC; } _drawTextPos[0] += iTotalWidth; @@ -274,48 +383,47 @@ void CEngineSurface :: drawTexturedRect( int x0, int y0, int x1, int y1 ) void CEngineSurface :: pushMakeCurrent( Panel* panel, bool useInsets ) { - int inSets[4] = { 0, 0, 0, 0 }; + int insets[4] = { 0, 0, 0, 0 }; int absExtents[4]; int clipRect[4]; if( useInsets ) - { - panel->getInset( inSets[0], inSets[1], inSets[2], inSets[3] ); - } - + panel->getInset( insets[0], insets[1], insets[2], insets[3] ); panel->getAbsExtents( absExtents[0], absExtents[1], absExtents[2], absExtents[3] ); panel->getClipRect( clipRect[0], clipRect[1], clipRect[2], clipRect[3] ); - int i = _paintStack.AddToTail(); - paintState_t &paintState = _paintStack[i]; - paintState.m_pPanel = panel; + PaintStack *paintState = &paintStack[staticPaintStackPos]; + + assert( staticPaintStackPos < MAX_PAINT_STACK ); + + paintState->m_pPanel = panel; // determine corrected top left origin - paintState.iTranslateX = inSets[0] + absExtents[0] - _surfaceExtents[0]; - paintState.iTranslateY = inSets[1] + absExtents[1] - _surfaceExtents[1]; - + paintState->iTranslateX = insets[0] + absExtents[0]; + paintState->iTranslateY = insets[1] + absExtents[1]; // setup clipping rectangle for scissoring - paintState.iScissorLeft = clipRect[0] - _surfaceExtents[0]; - paintState.iScissorTop = clipRect[1] - _surfaceExtents[1]; - paintState.iScissorRight = clipRect[2] - _surfaceExtents[0]; - paintState.iScissorBottom = clipRect[3] - _surfaceExtents[1]; + paintState->iScissorLeft = clipRect[0]; + paintState->iScissorTop = clipRect[1]; + paintState->iScissorRight = clipRect[2]; + paintState->iScissorBottom = clipRect[3]; SetupPaintState( paintState ); + staticPaintStackPos++; } void CEngineSurface :: popMakeCurrent( Panel *panel ) { - int top = _paintStack.Count() - 1; + int top = staticPaintStackPos - 1; // more pops that pushes? - Assert( top >= 0 ); + assert( top >= 0 ); // didn't pop in reverse order of push? - Assert( _paintStack[top].m_pPanel == panel ); + assert( paintStack[top].m_pPanel == panel ); - _paintStack.Remove( top ); - - if( top > 0 ) SetupPaintState( _paintStack[top-1] ); + staticPaintStackPos--; + + if( top > 0 ) SetupPaintState( &paintStack[top-1] ); } bool CEngineSurface :: setFullscreenMode( int wide, int tall, int bpp )