add font alignment

This commit is contained in:
Glenn Maynard
2003-01-06 23:49:43 +00:00
parent 71bd9579e0
commit c6e63f37d3
3 changed files with 87 additions and 25 deletions
+32 -4
View File
@@ -37,6 +37,25 @@ void FontPage::Load( const CString &TexturePath, const FontPageSettings &cfg )
m_pTexture = TEXTUREMAN->LoadTexture( m_sTexturePath );
ASSERT( m_pTexture != NULL );
/* All characters on a page have the same vertical spacing, baseline
* and center. */
baseline = cfg.Baseline;
if(baseline == -1)
{
/* The default baseline is 75% down the frame; this is where it
* tends to be. */
baseline = int(m_pTexture->GetTextureFrameHeight() * .75f);
}
center = cfg.Center;
if(center == -1)
{
/* We don't know the center, so assume it's the center of the frame. */
center = m_pTexture->GetSourceFrameHeight()/2;
}
kanji = cfg.Kanji;
// load character widths
vector<int> FrameWidths;
int i;
@@ -66,7 +85,6 @@ void FontPage::Load( const CString &TexturePath, const FontPageSettings &cfg )
m_iCharToGlyphNo = cfg.CharToGlyphNo;
/* All characters on a page have the same vertical spacing. */
int LineSpacing = cfg.LineSpacing;
if(LineSpacing == -1)
LineSpacing = m_pTexture->GetSourceFrameHeight();
@@ -81,6 +99,8 @@ void FontPage::SetTextureCoords(const vector<int> &widths, int LineSpacing)
{
glyph g;
g.fp = this;
/* Make a copy of each texture rect, reducing each to the actual dimensions
* of the character (most characters don't take a full block). */
g.rect = *m_pTexture->GetTextureCoordRect(i);;
@@ -92,10 +112,11 @@ void FontPage::SetTextureCoords(const vector<int> &widths, int LineSpacing)
/* By default, advance one pixel more than the width. (This could be
* an option.) */
g.hadvance = int(g.width + 1);
g.vadvance = LineSpacing;
/* Shift the character up so the top of the rendered quad is at the top
* of the character. */
g.vshift = -(m_pTexture->GetSourceFrameHeight() - LineSpacing)/2.0f;
g.vshift = -(m_pTexture->GetSourceFrameHeight() - g.vadvance)/2.0f;
/* Do the same thing with X. Do this by changing the actual rendered
* rect, instead of shifting it, so we don't render more than we need to. */
@@ -115,7 +136,6 @@ void FontPage::SetTextureCoords(const vector<int> &widths, int LineSpacing)
g.rect.right -= fTexCoordsToChopOff/2;
}
g.vadvance = LineSpacing;
g.Texture = m_pTexture;
glyphs.push_back(g);
@@ -158,7 +178,6 @@ FontPage::~FontPage()
TEXTUREMAN->UnloadTexture( m_pTexture );
}
int Font::GetLineWidthInSourcePixels( const lstring &szLine ) const
{
int LineWidth = 0;
@@ -261,3 +280,12 @@ void Font::CapsOnly()
m_iCharToGlyph[(char) tolower(c)] = it->second;
}
}
void Font::SetDefaultGlyph(FontPage *fp)
{
ASSERT(fp);
ASSERT(!fp->glyphs.empty());
def = fp;
}
+25 -2
View File
@@ -15,7 +15,10 @@
#include "RageUtil.h"
#include "IniFile.h"
class FontPage;
struct glyph {
FontPage *fp;
RageTexture *Texture;
/* Number of pixels to advance horizontally after drawing this character. */
@@ -35,8 +38,11 @@ struct FontPageSettings {
int DrawExtraPixelsLeft,
DrawExtraPixelsRight,
AddToAllWidths,
LineSpacing;
LineSpacing,
Baseline,
Center;
float ScaleAllWidthsBy;
bool Kanji;
map<longchar,int> CharToGlyphNo;
/* If a value is missing, the width of the texture frame is used. */
@@ -46,7 +52,10 @@ struct FontPageSettings {
DrawExtraPixelsLeft(0), DrawExtraPixelsRight(0),
AddToAllWidths(0),
LineSpacing(-1),
ScaleAllWidthsBy(1)
ScaleAllWidthsBy(1),
Baseline(-1),
Center(-1),
Kanji(false)
{ }
};
@@ -67,6 +76,10 @@ public:
void Load( const CString &sASCIITexturePath, const FontPageSettings &cfg );
/* Page-global properties. */
int baseline, center;
bool kanji;
private:
void SetExtraPixels(int DrawExtraPixelsLeft, int DrawExtraPixelsRight);
void SetTextureCoords(const vector<int> &widths, int LineSpacing);
@@ -97,12 +110,22 @@ public:
/* Load font-wide settings. */
void CapsOnly();
int GetBaseline() const { return def->baseline; }
bool IsKanjiFont() const { return def->kanji; }
int GetCenter() const { return def->center; }
void SetDefaultGlyph(FontPage *fp);
static const longchar DEFAULT_GLYPH;
private:
/* List of pages and fonts that we're responsible for freeing. */
vector<FontPage *> pages;
vector<Font *> merged_fonts;
/* This is the primary fontpage of this font; font-wide baseline, ascender,
* etc. is pulled from it. */
FontPage *def;
};
#endif
+30 -19
View File
@@ -83,6 +83,9 @@ void FontManager::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, cons
ini.GetValueI( PageName, "AddToAllWidths", cfg.AddToAllWidths );
ini.GetValueF( PageName, "ScaleAllWidthsBy", cfg.ScaleAllWidthsBy );
ini.GetValueI( PageName, "LineSpacing", cfg.LineSpacing );
ini.GetValueI( PageName, "Baseline", cfg.Baseline );
ini.GetValueI( PageName, "Center", cfg.Center );
ini.GetValueB( PageName, "Kanji", cfg.Kanji );
/* Iterate over all keys. */
const IniFile::key *k = ini.GetKey(PageName);
@@ -264,9 +267,11 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC
}
LoadStack.push_back(sFontOrTextureFilePath);
}
/* The font is not already loaded. Figure out what we have. */
// LOG->Trace( "FontManager::LoadFont(%s).", sFontFilePath.GetString() );
/* Get the filenames associated with this font. */
CStringArray TexturePaths;
CString IniPath;
GetFontPaths(sFontOrTextureFilePath, TexturePaths, IniPath);
@@ -276,6 +281,7 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC
bool CapitalsOnly = false;
/* If we have an INI, load it. */
IniFile ini;
if( !IniPath.empty() )
{
@@ -288,7 +294,7 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC
{
/* Check to see if we need to import any other fonts. Do this
* before loading this font, so any characters in this font
* override those imported. */
* override imported characters. */
CString imports;
ini.GetValue( "main", "import", imports );
CStringArray ImportList;
@@ -304,6 +310,7 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC
LoadingDefaultFont = false;
}
/* Load imports. */
for(unsigned i = 0; i < ImportList.size(); ++i)
{
CString path = THEME->GetPathTo("Fonts", ImportList[i]);
@@ -312,42 +319,44 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC
}
/* Load each font page. */
int expect = -1;
for(unsigned i = 0; i < TexturePaths.size(); ++i)
{
FontPage *fp = new FontPage;
int frames;
{
int wide, high;
RageTexture::GetFrameDimensionsFromFileName(TexturePaths[i], &wide, &high );
frames = wide*high;
}
int frames = RageTexture::GetFrameCountFromFileName(TexturePaths[i]);
/* Grab the page name, eg "foo" from "Normal [foo].png". */
CString pagename = GetPageNameFromFileName(TexturePaths[i]);
/* Load settings for this page from the INI. */
FontPageSettings cfg;
if( !sChars.empty() )
/* If we have any characters to map, add them. */
for( unsigned n=0; n<sChars.size(); n++ )
{
/* Map characters to frames. */
for( int i=0; i<sChars.GetLength(); i++ )
{
char c = sChars[i];
cfg.CharToGlyphNo[c] = i;
}
expect = sChars.GetLength();
char c = sChars[n];
cfg.CharToGlyphNo[c] = n;
}
/* Go. */
LoadFontPageSettings(cfg, ini, pagename, frames);
fp->Load(TexturePaths[i], cfg);
if( expect != -1 && fp->m_pTexture->GetNumFrames() < expect )
/* Expect at least as many frames as we have premapped characters. */
if( unsigned(fp->m_pTexture->GetNumFrames()) < sChars.size() )
RageException::Throw( "The font '%s' has %d frames; expected at least %i frames.",
fp->m_pTexture->GetNumFrames(), expect );
fp->m_pTexture->GetNumFrames(), sChars.size() );
LOG->Trace("Adding page %s (%s) to %s; %i glyphs",
TexturePaths[i].GetString(), pagename.GetString(),
sFontOrTextureFilePath.GetString(), fp->m_iCharToGlyphNo.size());
pFont->AddPage(fp);
/* If this is the first font loaded, or it's called "main", this page's
* properties become the font's properties. */
if(i == 0 || pagename == "main")
pFont->SetDefaultGlyph(fp);
}
if(CapitalsOnly)
@@ -453,7 +462,7 @@ void FontManager::InitCharAliases()
if(!CharAliases.empty())
return;
/* XXX; these should be in a data file somewhere (theme metrics?)
* (The comments here are UTF-8; they won't show up in VC6.) */
* (The comments here are UTF-8; they won't show up in VC6.) */
CharAliases["default"] = Font::DEFAULT_GLYPH; /* ? */
CharAliases["kakumei1"] = 0x9769; /* 革 */
CharAliases["kakumei2"] = 0x547D; /* 命 */
@@ -464,7 +473,9 @@ void FontManager::InitCharAliases()
CharAliases["omega"] = 0x03a9; /* Ω */
CharAliases["whiteheart"] = 0x2661; /* ♡ */
CharAliases["blackstar"] = 0x2605; /* ★ */
CharAliases["whitestar"] = 0x2606; /* ☆ */
/* These are internal-use glyphs; they don't have real Unicode codepoints. */
CharAliases["up"] = 0x100000;
CharAliases["down"] = 0x100001;
CharAliases["left"] = 0x100002;