add font alignment
This commit is contained in:
+32
-4
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user