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 );
|
m_pTexture = TEXTUREMAN->LoadTexture( m_sTexturePath );
|
||||||
ASSERT( m_pTexture != NULL );
|
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
|
// load character widths
|
||||||
vector<int> FrameWidths;
|
vector<int> FrameWidths;
|
||||||
int i;
|
int i;
|
||||||
@@ -66,7 +85,6 @@ void FontPage::Load( const CString &TexturePath, const FontPageSettings &cfg )
|
|||||||
|
|
||||||
m_iCharToGlyphNo = cfg.CharToGlyphNo;
|
m_iCharToGlyphNo = cfg.CharToGlyphNo;
|
||||||
|
|
||||||
/* All characters on a page have the same vertical spacing. */
|
|
||||||
int LineSpacing = cfg.LineSpacing;
|
int LineSpacing = cfg.LineSpacing;
|
||||||
if(LineSpacing == -1)
|
if(LineSpacing == -1)
|
||||||
LineSpacing = m_pTexture->GetSourceFrameHeight();
|
LineSpacing = m_pTexture->GetSourceFrameHeight();
|
||||||
@@ -81,6 +99,8 @@ void FontPage::SetTextureCoords(const vector<int> &widths, int LineSpacing)
|
|||||||
{
|
{
|
||||||
glyph g;
|
glyph g;
|
||||||
|
|
||||||
|
g.fp = this;
|
||||||
|
|
||||||
/* Make a copy of each texture rect, reducing each to the actual dimensions
|
/* Make a copy of each texture rect, reducing each to the actual dimensions
|
||||||
* of the character (most characters don't take a full block). */
|
* of the character (most characters don't take a full block). */
|
||||||
g.rect = *m_pTexture->GetTextureCoordRect(i);;
|
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
|
/* By default, advance one pixel more than the width. (This could be
|
||||||
* an option.) */
|
* an option.) */
|
||||||
g.hadvance = int(g.width + 1);
|
g.hadvance = int(g.width + 1);
|
||||||
|
g.vadvance = LineSpacing;
|
||||||
|
|
||||||
/* Shift the character up so the top of the rendered quad is at the top
|
/* Shift the character up so the top of the rendered quad is at the top
|
||||||
* of the character. */
|
* 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
|
/* 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. */
|
* 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.rect.right -= fTexCoordsToChopOff/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
g.vadvance = LineSpacing;
|
|
||||||
g.Texture = m_pTexture;
|
g.Texture = m_pTexture;
|
||||||
|
|
||||||
glyphs.push_back(g);
|
glyphs.push_back(g);
|
||||||
@@ -158,7 +178,6 @@ FontPage::~FontPage()
|
|||||||
TEXTUREMAN->UnloadTexture( m_pTexture );
|
TEXTUREMAN->UnloadTexture( m_pTexture );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Font::GetLineWidthInSourcePixels( const lstring &szLine ) const
|
int Font::GetLineWidthInSourcePixels( const lstring &szLine ) const
|
||||||
{
|
{
|
||||||
int LineWidth = 0;
|
int LineWidth = 0;
|
||||||
@@ -261,3 +280,12 @@ void Font::CapsOnly()
|
|||||||
m_iCharToGlyph[(char) tolower(c)] = it->second;
|
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 "RageUtil.h"
|
||||||
#include "IniFile.h"
|
#include "IniFile.h"
|
||||||
|
|
||||||
|
class FontPage;
|
||||||
|
|
||||||
struct glyph {
|
struct glyph {
|
||||||
|
FontPage *fp;
|
||||||
RageTexture *Texture;
|
RageTexture *Texture;
|
||||||
|
|
||||||
/* Number of pixels to advance horizontally after drawing this character. */
|
/* Number of pixels to advance horizontally after drawing this character. */
|
||||||
@@ -35,8 +38,11 @@ struct FontPageSettings {
|
|||||||
int DrawExtraPixelsLeft,
|
int DrawExtraPixelsLeft,
|
||||||
DrawExtraPixelsRight,
|
DrawExtraPixelsRight,
|
||||||
AddToAllWidths,
|
AddToAllWidths,
|
||||||
LineSpacing;
|
LineSpacing,
|
||||||
|
Baseline,
|
||||||
|
Center;
|
||||||
float ScaleAllWidthsBy;
|
float ScaleAllWidthsBy;
|
||||||
|
bool Kanji;
|
||||||
|
|
||||||
map<longchar,int> CharToGlyphNo;
|
map<longchar,int> CharToGlyphNo;
|
||||||
/* If a value is missing, the width of the texture frame is used. */
|
/* If a value is missing, the width of the texture frame is used. */
|
||||||
@@ -46,7 +52,10 @@ struct FontPageSettings {
|
|||||||
DrawExtraPixelsLeft(0), DrawExtraPixelsRight(0),
|
DrawExtraPixelsLeft(0), DrawExtraPixelsRight(0),
|
||||||
AddToAllWidths(0),
|
AddToAllWidths(0),
|
||||||
LineSpacing(-1),
|
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 );
|
void Load( const CString &sASCIITexturePath, const FontPageSettings &cfg );
|
||||||
|
|
||||||
|
/* Page-global properties. */
|
||||||
|
int baseline, center;
|
||||||
|
bool kanji;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetExtraPixels(int DrawExtraPixelsLeft, int DrawExtraPixelsRight);
|
void SetExtraPixels(int DrawExtraPixelsLeft, int DrawExtraPixelsRight);
|
||||||
void SetTextureCoords(const vector<int> &widths, int LineSpacing);
|
void SetTextureCoords(const vector<int> &widths, int LineSpacing);
|
||||||
@@ -97,12 +110,22 @@ public:
|
|||||||
/* Load font-wide settings. */
|
/* Load font-wide settings. */
|
||||||
void CapsOnly();
|
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;
|
static const longchar DEFAULT_GLYPH;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* List of pages and fonts that we're responsible for freeing. */
|
/* List of pages and fonts that we're responsible for freeing. */
|
||||||
vector<FontPage *> pages;
|
vector<FontPage *> pages;
|
||||||
vector<Font *> merged_fonts;
|
vector<Font *> merged_fonts;
|
||||||
|
|
||||||
|
/* This is the primary fontpage of this font; font-wide baseline, ascender,
|
||||||
|
* etc. is pulled from it. */
|
||||||
|
FontPage *def;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ void FontManager::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, cons
|
|||||||
ini.GetValueI( PageName, "AddToAllWidths", cfg.AddToAllWidths );
|
ini.GetValueI( PageName, "AddToAllWidths", cfg.AddToAllWidths );
|
||||||
ini.GetValueF( PageName, "ScaleAllWidthsBy", cfg.ScaleAllWidthsBy );
|
ini.GetValueF( PageName, "ScaleAllWidthsBy", cfg.ScaleAllWidthsBy );
|
||||||
ini.GetValueI( PageName, "LineSpacing", cfg.LineSpacing );
|
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. */
|
/* Iterate over all keys. */
|
||||||
const IniFile::key *k = ini.GetKey(PageName);
|
const IniFile::key *k = ini.GetKey(PageName);
|
||||||
@@ -264,9 +267,11 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC
|
|||||||
}
|
}
|
||||||
LoadStack.push_back(sFontOrTextureFilePath);
|
LoadStack.push_back(sFontOrTextureFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The font is not already loaded. Figure out what we have. */
|
/* The font is not already loaded. Figure out what we have. */
|
||||||
// LOG->Trace( "FontManager::LoadFont(%s).", sFontFilePath.GetString() );
|
// LOG->Trace( "FontManager::LoadFont(%s).", sFontFilePath.GetString() );
|
||||||
|
|
||||||
|
/* Get the filenames associated with this font. */
|
||||||
CStringArray TexturePaths;
|
CStringArray TexturePaths;
|
||||||
CString IniPath;
|
CString IniPath;
|
||||||
GetFontPaths(sFontOrTextureFilePath, TexturePaths, IniPath);
|
GetFontPaths(sFontOrTextureFilePath, TexturePaths, IniPath);
|
||||||
@@ -276,6 +281,7 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC
|
|||||||
|
|
||||||
bool CapitalsOnly = false;
|
bool CapitalsOnly = false;
|
||||||
|
|
||||||
|
/* If we have an INI, load it. */
|
||||||
IniFile ini;
|
IniFile ini;
|
||||||
if( !IniPath.empty() )
|
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
|
/* Check to see if we need to import any other fonts. Do this
|
||||||
* before loading this font, so any characters in this font
|
* before loading this font, so any characters in this font
|
||||||
* override those imported. */
|
* override imported characters. */
|
||||||
CString imports;
|
CString imports;
|
||||||
ini.GetValue( "main", "import", imports );
|
ini.GetValue( "main", "import", imports );
|
||||||
CStringArray ImportList;
|
CStringArray ImportList;
|
||||||
@@ -304,6 +310,7 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC
|
|||||||
LoadingDefaultFont = false;
|
LoadingDefaultFont = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Load imports. */
|
||||||
for(unsigned i = 0; i < ImportList.size(); ++i)
|
for(unsigned i = 0; i < ImportList.size(); ++i)
|
||||||
{
|
{
|
||||||
CString path = THEME->GetPathTo("Fonts", ImportList[i]);
|
CString path = THEME->GetPathTo("Fonts", ImportList[i]);
|
||||||
@@ -312,42 +319,44 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load each font page. */
|
/* Load each font page. */
|
||||||
int expect = -1;
|
|
||||||
for(unsigned i = 0; i < TexturePaths.size(); ++i)
|
for(unsigned i = 0; i < TexturePaths.size(); ++i)
|
||||||
{
|
{
|
||||||
FontPage *fp = new FontPage;
|
FontPage *fp = new FontPage;
|
||||||
int frames;
|
|
||||||
{
|
int frames = RageTexture::GetFrameCountFromFileName(TexturePaths[i]);
|
||||||
int wide, high;
|
|
||||||
RageTexture::GetFrameDimensionsFromFileName(TexturePaths[i], &wide, &high );
|
|
||||||
frames = wide*high;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Grab the page name, eg "foo" from "Normal [foo].png". */
|
/* Grab the page name, eg "foo" from "Normal [foo].png". */
|
||||||
CString pagename = GetPageNameFromFileName(TexturePaths[i]);
|
CString pagename = GetPageNameFromFileName(TexturePaths[i]);
|
||||||
|
|
||||||
|
/* Load settings for this page from the INI. */
|
||||||
FontPageSettings cfg;
|
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. */
|
char c = sChars[n];
|
||||||
for( int i=0; i<sChars.GetLength(); i++ )
|
cfg.CharToGlyphNo[c] = n;
|
||||||
{
|
|
||||||
char c = sChars[i];
|
|
||||||
cfg.CharToGlyphNo[c] = i;
|
|
||||||
}
|
|
||||||
expect = sChars.GetLength();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Go. */
|
||||||
LoadFontPageSettings(cfg, ini, pagename, frames);
|
LoadFontPageSettings(cfg, ini, pagename, frames);
|
||||||
fp->Load(TexturePaths[i], cfg);
|
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.",
|
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",
|
LOG->Trace("Adding page %s (%s) to %s; %i glyphs",
|
||||||
TexturePaths[i].GetString(), pagename.GetString(),
|
TexturePaths[i].GetString(), pagename.GetString(),
|
||||||
sFontOrTextureFilePath.GetString(), fp->m_iCharToGlyphNo.size());
|
sFontOrTextureFilePath.GetString(), fp->m_iCharToGlyphNo.size());
|
||||||
pFont->AddPage(fp);
|
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)
|
if(CapitalsOnly)
|
||||||
@@ -453,7 +462,7 @@ void FontManager::InitCharAliases()
|
|||||||
if(!CharAliases.empty())
|
if(!CharAliases.empty())
|
||||||
return;
|
return;
|
||||||
/* XXX; these should be in a data file somewhere (theme metrics?)
|
/* 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["default"] = Font::DEFAULT_GLYPH; /* ? */
|
||||||
CharAliases["kakumei1"] = 0x9769; /* 革 */
|
CharAliases["kakumei1"] = 0x9769; /* 革 */
|
||||||
CharAliases["kakumei2"] = 0x547D; /* 命 */
|
CharAliases["kakumei2"] = 0x547D; /* 命 */
|
||||||
@@ -464,7 +473,9 @@ void FontManager::InitCharAliases()
|
|||||||
CharAliases["omega"] = 0x03a9; /* Ω */
|
CharAliases["omega"] = 0x03a9; /* Ω */
|
||||||
CharAliases["whiteheart"] = 0x2661; /* ♡ */
|
CharAliases["whiteheart"] = 0x2661; /* ♡ */
|
||||||
CharAliases["blackstar"] = 0x2605; /* ★ */
|
CharAliases["blackstar"] = 0x2605; /* ★ */
|
||||||
|
CharAliases["whitestar"] = 0x2606; /* ☆ */
|
||||||
|
|
||||||
|
/* These are internal-use glyphs; they don't have real Unicode codepoints. */
|
||||||
CharAliases["up"] = 0x100000;
|
CharAliases["up"] = 0x100000;
|
||||||
CharAliases["down"] = 0x100001;
|
CharAliases["down"] = 0x100001;
|
||||||
CharAliases["left"] = 0x100002;
|
CharAliases["left"] = 0x100002;
|
||||||
|
|||||||
Reference in New Issue
Block a user