finish up ranges, other minor fixes
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
#include "ThemeManager.h"
|
#include "ThemeManager.h"
|
||||||
#include "GameConstantsAndTypes.h"
|
#include "GameConstantsAndTypes.h"
|
||||||
#include "Font.h"
|
#include "Font.h"
|
||||||
|
#include "FontCharAliases.h"
|
||||||
|
|
||||||
/* XXX:
|
/* XXX:
|
||||||
* We need some kind of font modifier string for metrics. For example,
|
* We need some kind of font modifier string for metrics. For example,
|
||||||
@@ -214,7 +215,7 @@ void BitmapText::SetText( CString sText, bool DoSubst )
|
|||||||
ASSERT( m_pFont );
|
ASSERT( m_pFont );
|
||||||
|
|
||||||
if(DoSubst)
|
if(DoSubst)
|
||||||
FontManager::ReplaceMarkers(sText);
|
FontCharAliases::ReplaceMarkers(sText);
|
||||||
|
|
||||||
if(m_szText == sText)
|
if(m_szText == sText)
|
||||||
return;
|
return;
|
||||||
|
|||||||
+107
-36
@@ -22,6 +22,8 @@
|
|||||||
#include "GameState.h"
|
#include "GameState.h"
|
||||||
#include "ThemeManager.h"
|
#include "ThemeManager.h"
|
||||||
#include "GameManager.h"
|
#include "GameManager.h"
|
||||||
|
#include "FontCharmaps.h"
|
||||||
|
#include "FontCharAliases.h"
|
||||||
|
|
||||||
const longchar Font::DEFAULT_GLYPH = 0xFFFFFF;
|
const longchar Font::DEFAULT_GLYPH = 0xFFFFFF;
|
||||||
|
|
||||||
@@ -45,6 +47,11 @@ void FontPage::Load( const FontPageSettings &cfg )
|
|||||||
// load character widths
|
// load character widths
|
||||||
vector<int> FrameWidths;
|
vector<int> FrameWidths;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
int default_width = m_pTexture->GetSourceFrameWidth();
|
||||||
|
if(cfg.DefaultWidth != -1)
|
||||||
|
default_width = cfg.DefaultWidth;
|
||||||
|
|
||||||
// Assume each character is the width of the frame by default.
|
// Assume each character is the width of the frame by default.
|
||||||
for( i=0; i<m_pTexture->GetNumFrames(); i++ )
|
for( i=0; i<m_pTexture->GetNumFrames(); i++ )
|
||||||
{
|
{
|
||||||
@@ -53,19 +60,19 @@ void FontPage::Load( const FontPageSettings &cfg )
|
|||||||
{
|
{
|
||||||
FrameWidths.push_back(it->second);
|
FrameWidths.push_back(it->second);
|
||||||
} else {
|
} else {
|
||||||
FrameWidths.push_back(m_pTexture->GetSourceFrameWidth());
|
FrameWidths.push_back(default_width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cfg.AddToAllWidths )
|
if( cfg.AddToAllWidths )
|
||||||
{
|
{
|
||||||
for( int i=0; i<256; i++ )
|
for( int i=0; i<m_pTexture->GetNumFrames(); i++ )
|
||||||
FrameWidths[i] += cfg.AddToAllWidths;
|
FrameWidths[i] += cfg.AddToAllWidths;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cfg.ScaleAllWidthsBy != 1 )
|
if( cfg.ScaleAllWidthsBy != 1 )
|
||||||
{
|
{
|
||||||
for( int i=0; i<256; i++ )
|
for( int i=0; i<m_pTexture->GetNumFrames(); i++ )
|
||||||
FrameWidths[i] = int(roundf( FrameWidths[i] * cfg.ScaleAllWidthsBy ));
|
FrameWidths[i] = int(roundf( FrameWidths[i] * cfg.ScaleAllWidthsBy ));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,21 +418,6 @@ void Font::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CStri
|
|||||||
cfg.CharToGlyphNo[c] = n;
|
cfg.CharToGlyphNo[c] = n;
|
||||||
}
|
}
|
||||||
int NumFrames = RageTexture::GetFrameCountFromFileName(TexturePath);
|
int NumFrames = RageTexture::GetFrameCountFromFileName(TexturePath);
|
||||||
if(NumFrames == 128 || NumFrames == 256)
|
|
||||||
{
|
|
||||||
/* If it's 128 or 256 frames, default to ASCII or ISO-8859-1,
|
|
||||||
* respectively. If it's anything else, we don't know what it
|
|
||||||
* is, so don't make any default mappings (the INI needs to do
|
|
||||||
* it itself). */
|
|
||||||
/*
|
|
||||||
if(NumFrames == 128)
|
|
||||||
cfg.MapRange("ASCII", 0, 127, 0);
|
|
||||||
else if(NumFrames == 256)
|
|
||||||
cfg.MapRange("ISO-8859-1", 0, 255, 0);
|
|
||||||
*/
|
|
||||||
for( longchar i=0; i<NumFrames; i++ )
|
|
||||||
cfg.CharToGlyphNo[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
ini.RenameKey("Char Widths", "main");
|
ini.RenameKey("Char Widths", "main");
|
||||||
|
|
||||||
@@ -439,6 +431,7 @@ void Font::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CStri
|
|||||||
ini.GetValueI( PageName, "LineSpacing", cfg.LineSpacing );
|
ini.GetValueI( PageName, "LineSpacing", cfg.LineSpacing );
|
||||||
ini.GetValueI( PageName, "Top", cfg.Top );
|
ini.GetValueI( PageName, "Top", cfg.Top );
|
||||||
ini.GetValueI( PageName, "Baseline", cfg.Baseline );
|
ini.GetValueI( PageName, "Baseline", cfg.Baseline );
|
||||||
|
ini.GetValueI( PageName, "DefaultWidth", cfg.DefaultWidth );
|
||||||
|
|
||||||
/* Iterate over all keys. */
|
/* Iterate over all keys. */
|
||||||
const IniFile::key *k = ini.GetKey(PageName);
|
const IniFile::key *k = ini.GetKey(PageName);
|
||||||
@@ -472,7 +465,6 @@ void Font::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CStri
|
|||||||
*/
|
*/
|
||||||
CString codepoint = val.substr(4); /* "XXXX" */
|
CString codepoint = val.substr(4); /* "XXXX" */
|
||||||
|
|
||||||
longchar c;
|
|
||||||
Game game = GAME_INVALID;
|
Game game = GAME_INVALID;
|
||||||
|
|
||||||
if(codepoint.find_first_of(' ') != codepoint.npos)
|
if(codepoint.find_first_of(' ') != codepoint.npos)
|
||||||
@@ -489,11 +481,13 @@ void Font::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CStri
|
|||||||
ini.GetPath().GetString(), gamename.GetString() );
|
ini.GetPath().GetString(), gamename.GetString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
longchar c=-1;
|
||||||
if(codepoint.substr(0, 2) == "U+" && IsHexVal(codepoint.substr(2)))
|
if(codepoint.substr(0, 2) == "U+" && IsHexVal(codepoint.substr(2)))
|
||||||
sscanf(codepoint.substr(2).c_str(), "%x", &c);
|
sscanf(codepoint.substr(2).c_str(), "%x", &c);
|
||||||
else if(FontManager::CharAliases.find(codepoint) != FontManager::CharAliases.end())
|
|
||||||
c = FontManager::CharAliases[codepoint];
|
|
||||||
else
|
else
|
||||||
|
c = FontCharAliases::GetChar(codepoint);
|
||||||
|
|
||||||
|
if(c == -1)
|
||||||
RageException::Throw( "Font definition '%s' has an invalid value '%s'.",
|
RageException::Throw( "Font definition '%s' has an invalid value '%s'.",
|
||||||
ini.GetPath().GetString(), val.GetString() );
|
ini.GetPath().GetString(), val.GetString() );
|
||||||
|
|
||||||
@@ -502,17 +496,13 @@ void Font::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CStri
|
|||||||
cfg.CharToGlyphNo[c] = atoi(data);
|
cfg.CharToGlyphNo[c] = atoi(data);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
/* not implemented yet */
|
|
||||||
if(val.substr(0, 6) == "RANGE ")
|
if(val.substr(0, 6) == "RANGE ")
|
||||||
{
|
{
|
||||||
/* range RANGE=first_frame
|
/* range CODESET=first_frame or
|
||||||
*
|
* range CODESET #start-end=first_frame
|
||||||
* RANGE is:
|
|
||||||
* CODESET or
|
|
||||||
* CODESET #start-end
|
|
||||||
* eg
|
* eg
|
||||||
* range ISO-8859-1=0 (default for 256-frame fonts)
|
* range CP1252=0 (default for 256-frame fonts)
|
||||||
* range ASCII=0 (default for 128-frame fonts)
|
* range ASCII=0 (default for 128-frame fonts)
|
||||||
*
|
*
|
||||||
* (Start and end are in hex.)
|
* (Start and end are in hex.)
|
||||||
@@ -524,20 +514,101 @@ void Font::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CStri
|
|||||||
* Map hiragana to 0-84:
|
* Map hiragana to 0-84:
|
||||||
* range Unicode #3041-3094=0
|
* range Unicode #3041-3094=0
|
||||||
*/
|
*/
|
||||||
CString range = val.substr(6);
|
vector<CString> matches;
|
||||||
unsigned first = 0, last = 0xFFFF; /* all */
|
bool match = regex("^RANGE ([A-Z\\-]+)( ?#([0-9A-F]+)-([0-9A-F]+))?$" , val, matches);
|
||||||
unsigned space = range.find_first_of(' ');
|
|
||||||
if(space != val.npos)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
ASSERT(matches.size() == 4); /* 4 parens */
|
||||||
|
|
||||||
|
if(!match || matches[0].empty())
|
||||||
|
RageException::Throw("Font definition '%s' has an invalid range '%s': parse error",
|
||||||
|
ini.GetPath().GetString(), val.GetString() );
|
||||||
|
|
||||||
|
/* We must have either 1 match (just the codeset) or 4 (the whole thing). */
|
||||||
|
|
||||||
|
int cnt = -1;
|
||||||
|
int first = 0;
|
||||||
|
if(!matches[2].empty())
|
||||||
|
{
|
||||||
|
sscanf(matches[2].GetString(), "%x", &first);
|
||||||
|
int last;
|
||||||
|
sscanf(matches[3].GetString(), "%x", &last);
|
||||||
|
if(last < first)
|
||||||
|
RageException::Throw("Font definition '%s' has an invalid range '%s': %i < %i.",
|
||||||
|
ini.GetPath().GetString(), val.GetString(), last < first );
|
||||||
|
|
||||||
|
cnt = last-first+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CString ret = cfg.MapRange(matches[0], first, atoi(data), cnt);
|
||||||
|
if(!ret.empty())
|
||||||
|
RageException::Throw("Font definition '%s' has an invalid range '%s': %s.",
|
||||||
|
ini.GetPath().GetString(), val.GetString(), ret.GetString() );
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If it's 128 or 256 frames, default to ASCII or CP1252,
|
||||||
|
* respectively. If it's anything else, we don't know what it
|
||||||
|
* is, so don't make any default mappings (the INI needs to do
|
||||||
|
* it itself). */
|
||||||
|
if(cfg.CharToGlyphNo.empty() && NumFrames == 128)
|
||||||
|
cfg.MapRange("ascii", 0, 0, -1);
|
||||||
|
else if(cfg.CharToGlyphNo.empty() && NumFrames == 256)
|
||||||
|
cfg.MapRange("cp1252", 0, 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CString FontPageSettings::MapRange(CString Mapping, int map_offset, int glyphno, int cnt)
|
||||||
|
{
|
||||||
|
if(!Mapping.CompareNoCase("Unicode"))
|
||||||
|
{
|
||||||
|
/* Special case. */
|
||||||
|
if(cnt == -1)
|
||||||
|
return "Can't map all of Unicode to one font page"; /* don't do that */
|
||||||
|
|
||||||
|
/* What's a practical limit? A 2048x2048 texture could contain 16x16 characters,
|
||||||
|
* which is 16384 glyphs. (Use a grayscale map and that's only 4 megs.) Let's use
|
||||||
|
* that as a cap. (We don't want to go crazy if someone says "range Unicode
|
||||||
|
* #0-FFFFFFFF".) */
|
||||||
|
if(cnt > 16384)
|
||||||
|
return ssprintf("Can't map %i glyphs to one font page", cnt);
|
||||||
|
|
||||||
|
while(cnt)
|
||||||
|
{
|
||||||
|
CharToGlyphNo[map_offset] = glyphno;
|
||||||
|
map_offset++;
|
||||||
|
glyphno++;
|
||||||
|
cnt--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const wchar_t *mapping = FontCharmaps::get_char_map(Mapping);
|
||||||
|
if(mapping == NULL)
|
||||||
|
return "Unknown mapping";
|
||||||
|
|
||||||
|
while(*mapping != 0 && map_offset) { mapping++; map_offset--; }
|
||||||
|
if(map_offset)
|
||||||
|
return "Map overflow"; /* there aren't enough characters in the map */
|
||||||
|
|
||||||
|
/* If cnt is -1, set it to the number of characters in the map. */
|
||||||
|
if(cnt == -1)
|
||||||
|
for(cnt = 0; mapping[cnt] != 0; ++cnt) ;
|
||||||
|
|
||||||
|
while(*mapping != 0)
|
||||||
|
{
|
||||||
|
if(*mapping != FontCharmaps::M_SKIP)
|
||||||
|
CharToGlyphNo[*mapping] = glyphno;
|
||||||
|
mapping++;
|
||||||
|
glyphno++;
|
||||||
|
cnt--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cnt)
|
||||||
|
return "Map overflow"; /* there aren't enough characters in the map */
|
||||||
|
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static CStringArray LoadStack;
|
static CStringArray LoadStack;
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ struct FontPageSettings
|
|||||||
AddToAllWidths,
|
AddToAllWidths,
|
||||||
LineSpacing,
|
LineSpacing,
|
||||||
Top,
|
Top,
|
||||||
Baseline;
|
Baseline,
|
||||||
|
DefaultWidth;
|
||||||
float ScaleAllWidthsBy;
|
float ScaleAllWidthsBy;
|
||||||
|
|
||||||
map<longchar,int> CharToGlyphNo;
|
map<longchar,int> CharToGlyphNo;
|
||||||
@@ -56,8 +57,13 @@ struct FontPageSettings
|
|||||||
LineSpacing(-1),
|
LineSpacing(-1),
|
||||||
ScaleAllWidthsBy(1),
|
ScaleAllWidthsBy(1),
|
||||||
Top(-1),
|
Top(-1),
|
||||||
Baseline(-1)
|
Baseline(-1),
|
||||||
|
DefaultWidth(-1)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
/* Map a range from a character map to glyphs. If cnt is -1, map the
|
||||||
|
* whole map. Returns "" or an error message. */
|
||||||
|
CString MapRange(CString Mapping, int map_offset, int glyph_offset, int cnt);
|
||||||
};
|
};
|
||||||
|
|
||||||
class FontPage
|
class FontPage
|
||||||
|
|||||||
@@ -19,9 +19,6 @@
|
|||||||
#include "RageException.h"
|
#include "RageException.h"
|
||||||
#include "RageTimer.h"
|
#include "RageTimer.h"
|
||||||
|
|
||||||
FontManager::aliasmap FontManager::CharAliases;
|
|
||||||
map<CString,CString> FontManager::CharAliasRepl;
|
|
||||||
|
|
||||||
FontManager* FONT = NULL;
|
FontManager* FONT = NULL;
|
||||||
|
|
||||||
FontManager::FontManager()
|
FontManager::FontManager()
|
||||||
@@ -68,8 +65,6 @@ void FontManager::ReloadFonts()
|
|||||||
|
|
||||||
Font* FontManager::LoadFont( const CString &sFontOrTextureFilePath, CString sChars )
|
Font* FontManager::LoadFont( const CString &sFontOrTextureFilePath, CString sChars )
|
||||||
{
|
{
|
||||||
InitCharAliases();
|
|
||||||
|
|
||||||
// Convert the path to lowercase so that we don't load duplicates.
|
// Convert the path to lowercase so that we don't load duplicates.
|
||||||
// Really, this does not solve the duplicate problem. We could have two copies
|
// Really, this does not solve the duplicate problem. We could have two copies
|
||||||
// of the same bitmap if there are equivalent but different paths
|
// of the same bitmap if there are equivalent but different paths
|
||||||
@@ -116,56 +111,3 @@ void FontManager::UnloadFont( Font *fp )
|
|||||||
|
|
||||||
RageException::Throw( "Unloaded an unknown font (%p)", fp );
|
RageException::Throw( "Unloaded an unknown font (%p)", fp );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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.) */
|
|
||||||
CharAliases["default"] = Font::DEFAULT_GLYPH; /* ? */
|
|
||||||
CharAliases["kakumei1"] = 0x9769; /* 革 */
|
|
||||||
CharAliases["kakumei2"] = 0x547D; /* 命 */
|
|
||||||
CharAliases["matsuri"] = 0x796D; /* 祭 */
|
|
||||||
CharAliases["oni"] = 0x9B3C; /* 鬼 */
|
|
||||||
CharAliases["michi"] = 0x9053; /* 道 */
|
|
||||||
CharAliases["futatsu"] = 0x5F10; /* 弐 */
|
|
||||||
CharAliases["omega"] = 0x03a9; /* Ω */
|
|
||||||
CharAliases["whiteheart"] = 0x2661; /* ♡ */
|
|
||||||
CharAliases["blackstar"] = 0x2605; /* ★ */
|
|
||||||
CharAliases["whitestar"] = 0x2606; /* ☆ */
|
|
||||||
CharAliases["flipped-a"] = 0x2200; /* ∀ */
|
|
||||||
|
|
||||||
/* These are internal-use glyphs; they don't have real Unicode codepoints. */
|
|
||||||
CharAliases["up"] = 0xE000;
|
|
||||||
CharAliases["down"] = 0xE001;
|
|
||||||
CharAliases["left"] = 0xE002;
|
|
||||||
CharAliases["right"] = 0xE003;
|
|
||||||
CharAliases["menuup"] = 0xE004;
|
|
||||||
CharAliases["menudown"] = 0xE005;
|
|
||||||
CharAliases["menuleft"] = 0xE006;
|
|
||||||
CharAliases["menuright"] = 0xE007;
|
|
||||||
CharAliases["start"] = 0xE008;
|
|
||||||
|
|
||||||
CharAliases["invalid"] = INVALID_CHAR; /* 0xFFFF */
|
|
||||||
|
|
||||||
for(aliasmap::const_iterator i = CharAliases.begin(); i != CharAliases.end(); ++i)
|
|
||||||
{
|
|
||||||
CString from = ssprintf("&%s;", i->first.GetString());
|
|
||||||
CString to = LcharToUTF8(i->second);
|
|
||||||
from.MakeUpper();
|
|
||||||
CharAliasRepl[from] = to;
|
|
||||||
LOG->Trace("from '%s' to '%s'", from.GetString(), to.GetString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Replace all &markers; and &#NNNN;s with UTF-8. I'm not really
|
|
||||||
* sure where to put this; this is used elsewhere, too. */
|
|
||||||
void FontManager::ReplaceMarkers( CString &sText )
|
|
||||||
{
|
|
||||||
InitCharAliases();
|
|
||||||
ReplaceText(sText, FontManager::CharAliasRepl);
|
|
||||||
Replace_Unicode_Markers(sText);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,16 +42,9 @@ public:
|
|||||||
static longchar MakeGameGlyph(longchar c, Game g);
|
static longchar MakeGameGlyph(longchar c, Game g);
|
||||||
static bool ExtractGameGlyph(longchar ch, int &c, Game &g);
|
static bool ExtractGameGlyph(longchar ch, int &c, Game &g);
|
||||||
|
|
||||||
typedef map<CString, longchar, StdStringLessNoCase> aliasmap;
|
|
||||||
static aliasmap CharAliases;
|
|
||||||
static map<CString,CString> CharAliasRepl;
|
|
||||||
|
|
||||||
static void ReplaceMarkers( CString &sText );
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// map from file name to a texture holder
|
// map from file name to a texture holder
|
||||||
map<CString, Font*> m_mapPathToFont;
|
map<CString, Font*> m_mapPathToFont;
|
||||||
static void InitCharAliases();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FontManager* FONT; // global and accessable from anywhere in our program
|
extern FontManager* FONT; // global and accessable from anywhere in our program
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#include "GameConstantsAndTypes.h"
|
#include "GameConstantsAndTypes.h"
|
||||||
#include "PrefsManager.h"
|
#include "PrefsManager.h"
|
||||||
#include "ThemeManager.h"
|
#include "ThemeManager.h"
|
||||||
#include "FontManager.h"
|
#include "FontCharAliases.h"
|
||||||
|
|
||||||
const float QUESTION_X = CENTER_X;
|
const float QUESTION_X = CENTER_X;
|
||||||
const float QUESTION_Y = CENTER_Y - 60;
|
const float QUESTION_Y = CENTER_Y - 60;
|
||||||
@@ -199,7 +199,7 @@ void ScreenTextEntry::MenuStart( PlayerNumber pn )
|
|||||||
if( m_pOnOK )
|
if( m_pOnOK )
|
||||||
{
|
{
|
||||||
CString ret = LStringToCString(m_sAnswer);
|
CString ret = LStringToCString(m_sAnswer);
|
||||||
FontManager::ReplaceMarkers(ret);
|
FontCharAliases::ReplaceMarkers(ret);
|
||||||
m_pOnOK( ret );
|
m_pOnOK( ret );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user