Font paths must be prefix-unique, like other assets. cleanup
This commit is contained in:
+25
-133
@@ -338,112 +338,17 @@ void Font::SetDefaultGlyph( FontPage *pPage )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CString Font::GetFontName( CString sFileName )
|
/* Given the INI for a font, find all of the texture pages for the font. */
|
||||||
|
void Font::GetFontPaths( const CString &sFontIniPath, CStringArray &asTexturePathsOut )
|
||||||
{
|
{
|
||||||
CString sOrig = sFileName;
|
CString sPrefix = SetExtension( sFontIniPath, "" );
|
||||||
|
|
||||||
CString sDir, sFName, sExt;
|
|
||||||
splitpath( sFileName, sDir, sFName, sExt );
|
|
||||||
sFileName = sFName;
|
|
||||||
|
|
||||||
/* If it ends in an extension, remove it. */
|
|
||||||
static Regex drop_ext( "\\....$" );
|
|
||||||
if( drop_ext.Compare(sFileName) )
|
|
||||||
sFileName.erase( sFileName.size()-4 );
|
|
||||||
|
|
||||||
/* If it ends in a resolution spec, remove it. */
|
|
||||||
CStringArray asMatch;
|
|
||||||
static Regex ResSpec( "( \\(res [0-9]+x[0-9]+\\))$" );
|
|
||||||
if( ResSpec.Compare(sFileName, asMatch) )
|
|
||||||
sFileName.erase(sFileName.size()-asMatch[0].size());
|
|
||||||
|
|
||||||
/* If it ends in a dimension spec, remove it. */
|
|
||||||
static Regex DimSpec( "( [0-9]+x[0-9]+)$" );
|
|
||||||
if( DimSpec.Compare(sFileName, asMatch) )
|
|
||||||
sFileName.erase( sFileName.size()-asMatch[0].size() );
|
|
||||||
|
|
||||||
/* If it ends in texture hints, remove them. */
|
|
||||||
static Regex Hints( "( \\([^\\)]+\\))$" );
|
|
||||||
if( Hints.Compare(sFileName, asMatch) )
|
|
||||||
sFileName.erase( sFileName.size()-asMatch[0].size() );
|
|
||||||
|
|
||||||
/* If it ends in a page name, remove it. */
|
|
||||||
static Regex PageName("( \\[.+\\])$");
|
|
||||||
if( PageName.Compare( sFileName, asMatch ) )
|
|
||||||
sFileName.erase( sFileName.size()-asMatch[0].size() );
|
|
||||||
|
|
||||||
TrimRight( sFileName );
|
|
||||||
|
|
||||||
if( sFileName.empty() )
|
|
||||||
RageException::Throw( "Can't parse font filename \"%s\"", sOrig.c_str() );
|
|
||||||
|
|
||||||
sFileName.MakeLower();
|
|
||||||
return sFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Font::WeedFontNames( vector<CString> &v, const CString &sFileName )
|
|
||||||
{
|
|
||||||
CString sFontName = Font::GetFontName( sFileName );
|
|
||||||
|
|
||||||
/* Weed out false matches. (For example, this gets rid of "normal2" when
|
|
||||||
* we're really looking for "normal".) */
|
|
||||||
for( unsigned i = 0; i < v.size(); )
|
|
||||||
{
|
|
||||||
if( sFontName.CompareNoCase(Font::GetFontName(v[i])) )
|
|
||||||
v.erase( v.begin()+i );
|
|
||||||
else
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given a file in a font, find all of the files for the font.
|
|
||||||
*
|
|
||||||
* Possibilities:
|
|
||||||
*
|
|
||||||
* Normal 16x16.png
|
|
||||||
* Normal [other] 16x16.png
|
|
||||||
* Normal [more] 8x8.png
|
|
||||||
* Normal 16x16.ini
|
|
||||||
* Normal.ini
|
|
||||||
*
|
|
||||||
* Any of the above should find all of the above. Allow the
|
|
||||||
* extension to be omitted. */
|
|
||||||
void Font::GetFontPaths( const CString &sFontOrTextureFilePath,
|
|
||||||
CStringArray &asTexturePathsOut, CString &sIniPath )
|
|
||||||
{
|
|
||||||
CString sDir, sFName, sExt;
|
|
||||||
splitpath( sFontOrTextureFilePath, sDir, sFName, sExt );
|
|
||||||
|
|
||||||
/* Don't give us a redir; resolve those before sending them here. */
|
|
||||||
ASSERT( sExt.CompareNoCase("redir") );
|
|
||||||
|
|
||||||
/* sFName can't be empty, or we don't know what to search for. */
|
|
||||||
ASSERT( !sFName.empty() );
|
|
||||||
|
|
||||||
CString sFontName = GetFontName( sFName );
|
|
||||||
|
|
||||||
CStringArray asFiles;
|
CStringArray asFiles;
|
||||||
GetDirListing( sDir+sFontName + "*", asFiles, false, false );
|
GetDirListing( sPrefix + "*", asFiles, false, true );
|
||||||
|
|
||||||
for( unsigned i = 0; i < asFiles.size(); ++i )
|
for( unsigned i = 0; i < asFiles.size(); ++i )
|
||||||
{
|
{
|
||||||
/* We now have a list of possibilities, but it may include false positives,
|
if( asFiles[i].Right(4).CompareNoCase(".ini"))
|
||||||
* such as "Normal2" when the font name is "Normal". Weed them. */
|
asTexturePathsOut.push_back( asFiles[i] );
|
||||||
if( GetFontName(asFiles[i]).CompareNoCase(sFontName) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* If it's an INI, and we don't already have an INI, use it. */
|
|
||||||
if( !asFiles[i].Right(4).CompareNoCase(".ini"))
|
|
||||||
{
|
|
||||||
if( !sIniPath.empty() )
|
|
||||||
RageException::Throw( "More than one INI found\n%s\n%s", sIniPath.c_str(), asFiles[i].c_str() );
|
|
||||||
|
|
||||||
sIniPath = sDir+asFiles[i];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
asTexturePathsOut.push_back( sDir+asFiles[i] );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -739,56 +644,43 @@ static CStringArray LoadStack;
|
|||||||
* Normal [more] 8x8.png
|
* Normal [more] 8x8.png
|
||||||
* Normal 16x16.ini (the 16x16 here is optional)
|
* Normal 16x16.ini (the 16x16 here is optional)
|
||||||
*
|
*
|
||||||
* Only one texture is required; the INI is optional. [1] This is
|
* One INI and at least one texture is required.
|
||||||
* designed to be backwards-compatible.
|
|
||||||
*
|
|
||||||
* sFontOrTextureFilePath can be a partial path, eg.
|
|
||||||
* "Themes/default/Fonts/Normal"
|
|
||||||
* or a complete path to a texture file (in which case no other
|
|
||||||
* files will be searched for).
|
|
||||||
*
|
*
|
||||||
* The entire font can be redirected; that's handled in ThemeManager.
|
* The entire font can be redirected; that's handled in ThemeManager.
|
||||||
* Individual font files can not be redirected.
|
* Individual font files can not be redirected.
|
||||||
*
|
*
|
||||||
* TODO:
|
* If a file has no characters and sChars is not set, it will receive a default
|
||||||
* [main]
|
|
||||||
* import=FontName,FontName2 (load other fonts)
|
|
||||||
*
|
|
||||||
* [1] If a file has no INI and sChars is not set, it will receive a default
|
|
||||||
* mapping of ASCII or ISO-8859-1 if the font has exactly 128 or 256 frames.
|
* mapping of ASCII or ISO-8859-1 if the font has exactly 128 or 256 frames.
|
||||||
* However, if it doesn't, we don't know what it is and the font will receive
|
* However, if it doesn't, we don't know what it is and the font will receive
|
||||||
* no default mapping. A font isn't useful with no characters mapped.
|
* no default mapping. A font isn't useful with no characters mapped.
|
||||||
*/
|
*/
|
||||||
void Font::Load(const CString &sFontOrTextureFilePath, CString sChars)
|
void Font::Load( const CString &sIniPath, CString sChars )
|
||||||
{
|
{
|
||||||
|
ASSERT_M( !GetExtension(sIniPath).CompareNoCase("ini"), sIniPath );
|
||||||
|
|
||||||
/* Check for recursion (recursive imports). */
|
/* Check for recursion (recursive imports). */
|
||||||
{
|
{
|
||||||
for(unsigned i = 0; i < LoadStack.size(); ++i)
|
for(unsigned i = 0; i < LoadStack.size(); ++i)
|
||||||
{
|
{
|
||||||
if(LoadStack[i] == sFontOrTextureFilePath)
|
if( LoadStack[i] == sIniPath )
|
||||||
{
|
{
|
||||||
CString str = join("\n", LoadStack);
|
CString str = join("\n", LoadStack);
|
||||||
str += "\n" + sFontOrTextureFilePath;
|
str += "\n" + sIniPath;
|
||||||
RageException::Throw("Font import recursion detected\n%s", str.c_str());
|
RageException::Throw("Font import recursion detected\n%s", str.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LoadStack.push_back(sFontOrTextureFilePath);
|
LoadStack.push_back( sIniPath );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The font is not already loaded. Figure out what we have. */
|
/* The font is not already loaded. Figure out what we have. */
|
||||||
CHECKPOINT_M( ssprintf("Font::Load(\"%s\",\"%s\").", sFontOrTextureFilePath.c_str(), m_sChars.c_str()) );
|
CHECKPOINT_M( ssprintf("Font::Load(\"%s\",\"%s\").", sIniPath.c_str(), m_sChars.c_str()) );
|
||||||
|
|
||||||
path = sFontOrTextureFilePath;
|
path = sIniPath;
|
||||||
m_sChars = sChars;
|
m_sChars = sChars;
|
||||||
|
|
||||||
/* Get the filenames associated with this font. */
|
/* Get the filenames associated with this font. */
|
||||||
CStringArray TexturePaths;
|
CStringArray asTexturePaths;
|
||||||
CString sIniPath;
|
GetFontPaths( sIniPath, asTexturePaths );
|
||||||
GetFontPaths( sFontOrTextureFilePath, TexturePaths, sIniPath );
|
|
||||||
|
|
||||||
/* If we don't have at least one INI or at least one texture path,
|
|
||||||
* we have nothing at all. */
|
|
||||||
ASSERT( !sIniPath.empty() || TexturePaths.size() );
|
|
||||||
|
|
||||||
bool bCapitalsOnly = false;
|
bool bCapitalsOnly = false;
|
||||||
|
|
||||||
@@ -818,7 +710,7 @@ void Font::Load(const CString &sFontOrTextureFilePath, CString sChars)
|
|||||||
CString path = THEME->GetPathF( "", ImportList[i], true );
|
CString path = THEME->GetPathF( "", ImportList[i], true );
|
||||||
if( path == "" )
|
if( path == "" )
|
||||||
{
|
{
|
||||||
LOG->Warn("Font \"%s\" imports a font \"%s\" that doesn't exist", sFontOrTextureFilePath.c_str(), ImportList[i].c_str());
|
LOG->Warn("Font \"%s\" imports a font \"%s\" that doesn't exist", sIniPath.c_str(), ImportList[i].c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -829,9 +721,9 @@ void Font::Load(const CString &sFontOrTextureFilePath, CString sChars)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load each font page. */
|
/* Load each font page. */
|
||||||
for(unsigned i = 0; i < TexturePaths.size(); ++i)
|
for(unsigned i = 0; i < asTexturePaths.size(); ++i)
|
||||||
{
|
{
|
||||||
const CString sTexturePath = TexturePaths[i];
|
const CString &sTexturePath = asTexturePaths[i];
|
||||||
|
|
||||||
FontPage *pPage = new FontPage;
|
FontPage *pPage = new FontPage;
|
||||||
|
|
||||||
@@ -840,8 +732,8 @@ void Font::Load(const CString &sFontOrTextureFilePath, CString sChars)
|
|||||||
|
|
||||||
/* Load settings for this page from the INI. */
|
/* Load settings for this page from the INI. */
|
||||||
FontPageSettings cfg;
|
FontPageSettings cfg;
|
||||||
LoadFontPageSettings( cfg, ini, TexturePaths[i], "common", sChars );
|
LoadFontPageSettings( cfg, ini, sTexturePath, "common", sChars );
|
||||||
LoadFontPageSettings( cfg, ini, TexturePaths[i], sPagename, sChars );
|
LoadFontPageSettings( cfg, ini, sTexturePath, sPagename, sChars );
|
||||||
|
|
||||||
/* Go. */
|
/* Go. */
|
||||||
pPage->Load( cfg );
|
pPage->Load( cfg );
|
||||||
@@ -855,7 +747,7 @@ void Font::Load(const CString &sFontOrTextureFilePath, CString sChars)
|
|||||||
if( it->second < pPage->m_pTexture->GetNumFrames() )
|
if( it->second < pPage->m_pTexture->GetNumFrames() )
|
||||||
continue; /* OK */
|
continue; /* OK */
|
||||||
CString sError = ssprintf( "The font '%s' maps %s to frame %i, but the font only has %i frames.",
|
CString sError = ssprintf( "The font '%s' maps %s to frame %i, but the font only has %i frames.",
|
||||||
TexturePaths[i].c_str(), WcharDisplayText(wchar_t(it->first)).c_str(), it->second, pPage->m_pTexture->GetNumFrames() );
|
sTexturePath.c_str(), WcharDisplayText(wchar_t(it->first)).c_str(), it->second, pPage->m_pTexture->GetNumFrames() );
|
||||||
RageException::Throw( sError );
|
RageException::Throw( sError );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -874,7 +766,7 @@ void Font::Load(const CString &sFontOrTextureFilePath, CString sChars)
|
|||||||
CapsOnly();
|
CapsOnly();
|
||||||
|
|
||||||
if( m_iCharToGlyph.empty() )
|
if( m_iCharToGlyph.empty() )
|
||||||
LOG->Warn("Font %s has no characters", sFontOrTextureFilePath.c_str());
|
LOG->Warn( "Font %s has no characters", sIniPath.c_str() );
|
||||||
|
|
||||||
LoadStack.pop_back();
|
LoadStack.pop_back();
|
||||||
|
|
||||||
|
|||||||
@@ -136,10 +136,6 @@ public:
|
|||||||
|
|
||||||
static const wchar_t DEFAULT_GLYPH;
|
static const wchar_t DEFAULT_GLYPH;
|
||||||
|
|
||||||
static CString GetFontName(CString FileName);
|
|
||||||
/* Remove filenames in 'v' that aren't in the same font as "FileName". */
|
|
||||||
static void WeedFontNames(vector<CString> &v, const CString &FileName);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* List of pages and fonts that we use (and are responsible for freeing). */
|
/* List of pages and fonts that we use (and are responsible for freeing). */
|
||||||
vector<FontPage *> m_apPages;
|
vector<FontPage *> m_apPages;
|
||||||
@@ -156,7 +152,7 @@ private:
|
|||||||
CString m_sChars;
|
CString m_sChars;
|
||||||
|
|
||||||
void LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const CString &sTexturePath, const CString &PageName, CString sChars );
|
void LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const CString &sTexturePath, const CString &PageName, CString sChars );
|
||||||
static void GetFontPaths( const CString &sFontOrTextureFilePath, CStringArray &TexturePaths, CString &IniPath );
|
static void GetFontPaths( const CString &sFontOrTextureFilePath, CStringArray &sTexturePaths );
|
||||||
CString GetPageNameFromFileName( const CString &sFilename );
|
CString GetPageNameFromFileName( const CString &sFilename );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user