finish up ranges, other minor fixes

This commit is contained in:
Glenn Maynard
2003-01-16 20:21:07 +00:00
parent a222aa7e75
commit 3ec2605b60
6 changed files with 119 additions and 106 deletions
+2 -1
View File
@@ -21,6 +21,7 @@
#include "ThemeManager.h"
#include "GameConstantsAndTypes.h"
#include "Font.h"
#include "FontCharAliases.h"
/* XXX:
* 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 );
if(DoSubst)
FontManager::ReplaceMarkers(sText);
FontCharAliases::ReplaceMarkers(sText);
if(m_szText == sText)
return;
+107 -36
View File
@@ -22,6 +22,8 @@
#include "GameState.h"
#include "ThemeManager.h"
#include "GameManager.h"
#include "FontCharmaps.h"
#include "FontCharAliases.h"
const longchar Font::DEFAULT_GLYPH = 0xFFFFFF;
@@ -45,6 +47,11 @@ void FontPage::Load( const FontPageSettings &cfg )
// load character widths
vector<int> FrameWidths;
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.
for( i=0; i<m_pTexture->GetNumFrames(); i++ )
{
@@ -53,19 +60,19 @@ void FontPage::Load( const FontPageSettings &cfg )
{
FrameWidths.push_back(it->second);
} else {
FrameWidths.push_back(m_pTexture->GetSourceFrameWidth());
FrameWidths.push_back(default_width);
}
}
if( cfg.AddToAllWidths )
{
for( int i=0; i<256; i++ )
for( int i=0; i<m_pTexture->GetNumFrames(); i++ )
FrameWidths[i] += cfg.AddToAllWidths;
}
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 ));
}
@@ -411,21 +418,6 @@ void Font::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CStri
cfg.CharToGlyphNo[c] = n;
}
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");
@@ -439,6 +431,7 @@ void Font::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CStri
ini.GetValueI( PageName, "LineSpacing", cfg.LineSpacing );
ini.GetValueI( PageName, "Top", cfg.Top );
ini.GetValueI( PageName, "Baseline", cfg.Baseline );
ini.GetValueI( PageName, "DefaultWidth", cfg.DefaultWidth );
/* Iterate over all keys. */
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" */
longchar c;
Game game = GAME_INVALID;
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() );
}
longchar c=-1;
if(codepoint.substr(0, 2) == "U+" && IsHexVal(codepoint.substr(2)))
sscanf(codepoint.substr(2).c_str(), "%x", &c);
else if(FontManager::CharAliases.find(codepoint) != FontManager::CharAliases.end())
c = FontManager::CharAliases[codepoint];
else
c = FontCharAliases::GetChar(codepoint);
if(c == -1)
RageException::Throw( "Font definition '%s' has an invalid value '%s'.",
ini.GetPath().GetString(), val.GetString() );
@@ -502,17 +496,13 @@ void Font::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CStri
cfg.CharToGlyphNo[c] = atoi(data);
continue;
}
#if 0
/* not implemented yet */
if(val.substr(0, 6) == "RANGE ")
{
/* range RANGE=first_frame
*
* RANGE is:
* CODESET or
* CODESET #start-end
/* range CODESET=first_frame or
* range CODESET #start-end=first_frame
* 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)
*
* (Start and end are in hex.)
@@ -524,20 +514,101 @@ void Font::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CStri
* Map hiragana to 0-84:
* range Unicode #3041-3094=0
*/
CString range = val.substr(6);
unsigned first = 0, last = 0xFFFF; /* all */
unsigned space = range.find_first_of(' ');
if(space != val.npos)
{
vector<CString> matches;
bool match = regex("^RANGE ([A-Z\\-]+)( ?#([0-9A-F]+)-([0-9A-F]+))?$" , val, matches);
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;
}
#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;
+8 -2
View File
@@ -43,7 +43,8 @@ struct FontPageSettings
AddToAllWidths,
LineSpacing,
Top,
Baseline;
Baseline,
DefaultWidth;
float ScaleAllWidthsBy;
map<longchar,int> CharToGlyphNo;
@@ -56,8 +57,13 @@ struct FontPageSettings
LineSpacing(-1),
ScaleAllWidthsBy(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
-58
View File
@@ -19,9 +19,6 @@
#include "RageException.h"
#include "RageTimer.h"
FontManager::aliasmap FontManager::CharAliases;
map<CString,CString> FontManager::CharAliasRepl;
FontManager* FONT = NULL;
FontManager::FontManager()
@@ -68,8 +65,6 @@ void FontManager::ReloadFonts()
Font* FontManager::LoadFont( const CString &sFontOrTextureFilePath, CString sChars )
{
InitCharAliases();
// 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
// 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 );
}
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);
}
-7
View File
@@ -42,16 +42,9 @@ public:
static longchar MakeGameGlyph(longchar 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:
// map from file name to a texture holder
map<CString, Font*> m_mapPathToFont;
static void InitCharAliases();
};
extern FontManager* FONT; // global and accessable from anywhere in our program
+2 -2
View File
@@ -18,7 +18,7 @@
#include "GameConstantsAndTypes.h"
#include "PrefsManager.h"
#include "ThemeManager.h"
#include "FontManager.h"
#include "FontCharAliases.h"
const float QUESTION_X = CENTER_X;
const float QUESTION_Y = CENTER_Y - 60;
@@ -199,7 +199,7 @@ void ScreenTextEntry::MenuStart( PlayerNumber pn )
if( m_pOnOK )
{
CString ret = LStringToCString(m_sAnswer);
FontManager::ReplaceMarkers(ret);
FontCharAliases::ReplaceMarkers(ret);
m_pOnOK( ret );
}
}