Set up texture coords for fonts in Font, so we don't have to deal with

it in BitmapText.
This commit is contained in:
Glenn Maynard
2003-01-03 20:59:50 +00:00
parent 55e92e771d
commit e89ddf7e3d
3 changed files with 92 additions and 61 deletions
+13 -33
View File
@@ -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;
+68 -26
View File
@@ -21,10 +21,8 @@
#include <stdio.h>
#include <assert.h>
Font::Font( const CString &sASCIITexturePath )
void Font::Init()
{
//LOG->Trace( "Font::LoadFromFontName(%s)", sASCIITexturePath.GetString() );
int i;
for( i=0; i<MAX_FONT_CHARS; i++ )
@@ -33,7 +31,16 @@ Font::Font( const CString &sASCIITexturePath )
m_iFrameNoToWidth[i] = -1;
}
m_bCapitalsOnly = false;
m_iRefCount = 1;
}
Font::Font( const CString &sASCIITexturePath )
{
//LOG->Trace( "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; i<MAX_FONT_CHARS; i++ )
{
m_iCharToFrameNo[i] = -1;
m_iFrameNoToWidth[i] = -1;
}
m_bCapitalsOnly = false;
m_iDrawExtraPixelsLeft = 0;
m_iDrawExtraPixelsRight = 0;
m_iRefCount = 1;
Init();
//
// load texture
@@ -114,12 +107,10 @@ Font::Font( const CString &sTexturePath, const CString& sCharacters )
m_sTexturePath = sTexturePath; // save
m_sTexturePath.MakeLower();
m_pTexture = TEXTUREMAN->LoadTexture( 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; i<sCharacters.GetLength(); i++ )
{
char c = sCharacters[i];
@@ -140,8 +132,58 @@ Font::Font( const CString &sTexturePath, const CString& sCharacters )
// Assume each character is the width of the frame.
for( i=0; i<(int)m_pTexture->GetNumFrames(); 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()
{
+11 -2
View File
@@ -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<int> m_Left, m_Right;
private:
vector<RectF> m_TextureCoordRects;
void SetExtraPixels(int DrawExtraPixelsLeft, int DrawExtraPixelsRight);
void SetTextureCoords();
};