From e89ddf7e3dd7c6d67ce7dcfd696a5906f94465a8 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Fri, 3 Jan 2003 20:59:50 +0000 Subject: [PATCH] Set up texture coords for fonts in Font, so we don't have to deal with it in BitmapText. --- stepmania/src/BitmapText.cpp | 46 +++++------------- stepmania/src/Font.cpp | 94 ++++++++++++++++++++++++++---------- stepmania/src/Font.h | 13 ++++- 3 files changed, 92 insertions(+), 61 deletions(-) diff --git a/stepmania/src/BitmapText.cpp b/stepmania/src/BitmapText.cpp index 74a04767cd..09aa37a4c1 100644 --- a/stepmania/src/BitmapText.cpp +++ b/stepmania/src/BitmapText.cpp @@ -160,7 +160,6 @@ void BitmapText::DrawPrimitives() // make the object in logical units centered at the origin const int iHeight = pTexture->GetSourceFrameHeight(); // height of a character const int iLineSpacing = m_pFont->m_iLineSpacing; // spacing between lines - const int iFrameWidth = pTexture->GetSourceFrameWidth(); // width of a character frame in logical units int iY; // the center position of the first row of characters switch( m_VertAlign ) @@ -191,44 +190,25 @@ void BitmapText::DrawPrimitives() const int iFrameNo = m_pFont->m_iCharToFrameNo[ (unsigned char)c ]; if( iFrameNo == -1 ) // this font doesn't impelemnt this character RageException::Throw( "The font '%s' does not implement the character '%c'", m_sFontFilePath.GetString(), c ); - const int iCharWidth = m_pFont->m_iFrameNoToWidth[iFrameNo]; - // The right side of any italic letter is being cropped. So, we're going to draw a little bit - // to the right of the normal character. - const int iDrawExtraPixelsLeft = min( m_pFont->m_iDrawExtraPixelsLeft, (iFrameWidth-iCharWidth)/2 ); - const int iDrawExtraPixelsRight = min( m_pFont->m_iDrawExtraPixelsRight, (iFrameWidth-iCharWidth)/2 ); + /* set vertex positions */ + v[iNumV++].p = RageVector3( (float)iX-m_pFont->m_Left[iFrameNo], iY-iHeight/2.0f, 0 ); // top left + v[iNumV++].p = RageVector3( (float)iX-m_pFont->m_Left[iFrameNo], iY+iHeight/2.0f, 0 ); // bottom left + v[iNumV++].p = RageVector3( (float)iX+m_pFont->m_Right[iFrameNo], iY+iHeight/2.0f, 0 ); // bottom right + v[iNumV++].p = RageVector3( (float)iX+m_pFont->m_Right[iFrameNo], iY-iHeight/2.0f, 0 ); // top right - // - // set vertex positions - // - v[iNumV++].p = RageVector3( (float)iX-iDrawExtraPixelsLeft, iY-iHeight/2.0f, 0 ); // top left - v[iNumV++].p = RageVector3( (float)iX-iDrawExtraPixelsLeft, iY+iHeight/2.0f, 0 ); // bottom left - v[iNumV++].p = RageVector3( (float)iX-iDrawExtraPixelsLeft+iCharWidth+iDrawExtraPixelsRight, iY+iHeight/2.0f, 0 ); // bottom right - v[iNumV++].p = RageVector3( (float)iX-iDrawExtraPixelsLeft+iCharWidth+iDrawExtraPixelsRight, iY-iHeight/2.0f, 0 ); // top right + /* Advance the cursor. */ + iX += m_pFont->m_iFrameNoToWidth[iFrameNo]; - iX += iCharWidth; - - // - // set texture coordinates - // + /* set texture coordinates */ iNumV -= 4; - RectF frectTexCoords = *pTexture->GetTextureCoordRect( iFrameNo ); + RectF frectTexCoords = m_pFont->GetTextureCoordRect( iFrameNo ); - // Tweak the textures frame rectangles so we don't draw extra - // to the left and right of the character, saving us fill rate. - float fPixelsToChopOff = pTexture->GetSourceFrameWidth() - (float)iCharWidth; - float fTexCoordsToChopOff = fPixelsToChopOff / pTexture->GetSourceWidth(); - frectTexCoords.left += fTexCoordsToChopOff/2; - frectTexCoords.right -= fTexCoordsToChopOff/2; - - const float fExtraTexCoordsLeft = iDrawExtraPixelsLeft / (float)pTexture->GetSourceWidth(); - const float fExtraTexCoordsRight = iDrawExtraPixelsRight / (float)pTexture->GetSourceWidth(); - - v[iNumV++].t = RageVector2( frectTexCoords.left - fExtraTexCoordsLeft, frectTexCoords.top ); // top left - v[iNumV++].t = RageVector2( frectTexCoords.left - fExtraTexCoordsLeft, frectTexCoords.bottom ); // bottom left - v[iNumV++].t = RageVector2( frectTexCoords.right + fExtraTexCoordsRight, frectTexCoords.bottom ); // bottom right - v[iNumV++].t = RageVector2( frectTexCoords.right + fExtraTexCoordsRight, frectTexCoords.top ); // top right + v[iNumV++].t = RageVector2( frectTexCoords.left, frectTexCoords.top ); // top left + v[iNumV++].t = RageVector2( frectTexCoords.left, frectTexCoords.bottom ); // bottom left + v[iNumV++].t = RageVector2( frectTexCoords.right, frectTexCoords.bottom ); // bottom right + v[iNumV++].t = RageVector2( frectTexCoords.right, frectTexCoords.top ); // top right } iY += iLineSpacing; diff --git a/stepmania/src/Font.cpp b/stepmania/src/Font.cpp index 3b393a570e..076d3076f1 100644 --- a/stepmania/src/Font.cpp +++ b/stepmania/src/Font.cpp @@ -21,10 +21,8 @@ #include #include -Font::Font( const CString &sASCIITexturePath ) +void Font::Init() { - //LOG->Trace( "Font::LoadFromFontName(%s)", sASCIITexturePath.GetString() ); - int i; for( i=0; iTrace( "Font::LoadFromFontName(%s)", sASCIITexturePath.GetString() ); + + Init(); // load texture m_sTexturePath = sASCIITexturePath; @@ -43,6 +50,7 @@ Font::Font( const CString &sASCIITexturePath ) if( m_pTexture->GetNumFrames() != 16*16 ) RageException::Throw( "The font '%s' has only %d frames. All fonts must have 16*16 frames.", m_sTexturePath.GetString() ); + int i; for( i=0; i<256; i++ ) m_iCharToFrameNo[i] = i; @@ -59,14 +67,11 @@ Font::Font( const CString &sASCIITexturePath ) if( !ini.GetValueI( "Char Widths", ssprintf("%d",i), m_iFrameNoToWidth[i] ) ) RageException::Throw( "Error reading width value '%d' from '%s'.", i, sIniPath.GetString() ); - m_bCapitalsOnly = false; ini.GetValueB( "Char Widths", "CapitalsOnly", m_bCapitalsOnly ); + int DrawExtraPixelsLeft = 0, DrawExtraPixelsRight = 0; - m_iDrawExtraPixelsLeft = 0; - ini.GetValueI( "Char Widths", "DrawExtraPixelsLeft", m_iDrawExtraPixelsLeft ); - - m_iDrawExtraPixelsRight = 0; - ini.GetValueI( "Char Widths", "DrawExtraPixelsRight", m_iDrawExtraPixelsRight ); + ini.GetValueI( "Char Widths", "DrawExtraPixelsLeft", DrawExtraPixelsLeft ); + ini.GetValueI( "Char Widths", "DrawExtraPixelsRight", DrawExtraPixelsRight ); int iAddToAllWidths = 0; if( ini.GetValueI( "Char Widths", "AddToAllWidths", iAddToAllWidths ) ) @@ -85,28 +90,16 @@ Font::Font( const CString &sASCIITexturePath ) m_iLineSpacing = m_pTexture->GetSourceFrameHeight(); ini.GetValueI( "Char Widths", "LineSpacing", m_iLineSpacing ); - // force widths to even number - for( i=0; i<256; i++ ) - if( m_iFrameNoToWidth[i]%2 == 1 ) - m_iFrameNoToWidth[i]++; + SetTextureCoords(); + SetExtraPixels(DrawExtraPixelsLeft, DrawExtraPixelsRight); } Font::Font( const CString &sTexturePath, const CString& sCharacters ) { //LOG->Trace( "Font::LoadFromFontName(%s)", sFontFilePath.GetString() ); - int i; - for( i=0; iLoadTexture( m_sTexturePath ); ASSERT( m_pTexture != NULL ); m_iLineSpacing = m_pTexture->GetSourceFrameHeight(); - // // find out what characters are in this font // @@ -129,6 +120,7 @@ Font::Font( const CString &sTexturePath, const CString& sCharacters ) m_sTexturePath.GetString(), m_pTexture->GetNumFrames(), sCharacters.GetLength() ); // set the char to frame number map + int i; for( i=0; iGetNumFrames(); i++ ) m_iFrameNoToWidth[i] = m_pTexture->GetSourceFrameWidth(); + + SetTextureCoords(); } +void Font::SetTextureCoords() +{ + // force widths to even number + // Why do this? It seems to just artificially widen some characters a little and + // make it look a little worse in 640x480 ... +/* for( i=0; i<256; i++ ) + if( m_iFrameNoToWidth[i]%2 == 1 ) + m_iFrameNoToWidth[i]++; +*/ + + for(int i = 0; i < m_pTexture->GetNumFrames(); ++i) + { + /* Make a copy of each texture rect, reducing each to the actual dimensions + * of the character (most characters don't take a full block). */ + RectF r = *m_pTexture->GetTextureCoordRect(i);; + + float fPixelsToChopOff = m_pTexture->GetSourceFrameWidth() - (float)m_iFrameNoToWidth[i]; + float fTexCoordsToChopOff = fPixelsToChopOff / m_pTexture->GetSourceWidth(); + + r.left += fTexCoordsToChopOff/2; + r.right -= fTexCoordsToChopOff/2; + m_TextureCoordRects.push_back(r); + + /* Add normal widths. */ + m_Left.push_back(0); + m_Right.push_back(m_iFrameNoToWidth[i]); + } +} + +void Font::SetExtraPixels(int DrawExtraPixelsLeft, int DrawExtraPixelsRight) +{ + /* Adjust for DrawExtraPixelsLeft and DrawExtraPixelsRight. */ + for(unsigned i = 0; i < m_TextureCoordRects.size(); ++i) + { + int iFrameWidth = m_pTexture->GetSourceFrameWidth(); + int iCharWidth = m_iFrameNoToWidth[i]; + + /* Extra pixels to draw to the left and right. */ + int ExtraLeft = min( DrawExtraPixelsLeft, (iFrameWidth-iCharWidth)/2 ); + int ExtraRight = min( DrawExtraPixelsRight, (iFrameWidth-iCharWidth)/2 ) + ExtraLeft; + + /* Move left and expand right. */ + m_TextureCoordRects[i].left -= float(ExtraLeft) / m_pTexture->GetSourceWidth(); + m_TextureCoordRects[i].right += float(ExtraRight) / m_pTexture->GetSourceWidth(); + m_Left[i] += ExtraLeft; + m_Right[i] += ExtraRight; + } +} Font::~Font() { diff --git a/stepmania/src/Font.h b/stepmania/src/Font.h index 84d2ab4e3f..09573c6436 100644 --- a/stepmania/src/Font.h +++ b/stepmania/src/Font.h @@ -22,6 +22,7 @@ public: Font( const CString &sASCIITexturePath ); Font( const CString &sTexturePath, const CString& sChars ); ~Font(); + void Init(); int GetLineWidthInSourcePixels( const CString &szLine ); @@ -31,13 +32,21 @@ public: RageTexture* m_pTexture; bool m_bCapitalsOnly; - int m_iDrawExtraPixelsLeft, m_iDrawExtraPixelsRight; // for italic fonts int m_iLineSpacing; int m_iCharToFrameNo[MAX_FONT_CHARS]; int m_iFrameNoToWidth[MAX_FONT_CHARS]; // in soure coordinate space -protected: + const RectF &GetTextureCoordRect( int frameNo ) const { return m_TextureCoordRects[frameNo]; } + + /* Source pixels to print to the left and right of each character. + * m_Left[] is usually 0. */ + vector m_Left, m_Right; + +private: + vector m_TextureCoordRects; + void SetExtraPixels(int DrawExtraPixelsLeft, int DrawExtraPixelsRight); + void SetTextureCoords(); };