在游戏制作中,需要将界面图形元素保存到一幅png图像中,然后在xml格式的imageset文件中指出每个元素的位置和大小,方便游戏程序加载使用。
这里将Fireworks切成很多小的图层导出为CSS的htm,然后提取生成imageset。
提取算法代码如下:
/************************************************************************
* AppMain
* Author: 陈相礼
* Time: 2010.01.15
* Compiler: VC8
************************************************************************/
#include "Html2Imageset.h"
void main( int argc, char **argv )
{
if ( argc != 2 )
{
return;
}
Html2Imageset test( argv[1] );
test.toImageset();
}
/************************************************************************
* Html2Imageset.h
* Author: 陈相礼
* Time: 2010.01.15
* Compiler: VC8
************************************************************************/
#pragma once
#include
#include
#include
using namespace std;
class Html2Imageset
{
typedef struct _tFmt
{
char label[128];
int xpos, ypox, width, height;
}Format;
public:
Html2Imageset() :
m_strPath(""),
m_fpIn(0),
m_fpOut(0),
m_bString(false)
{
m_bNumber[0] = false;
m_bNumber[1] = false;
m_bNumber[2] = false;
m_bNumber[3] = false;
};
Html2Imageset( const string &strPath );
~Html2Imageset();
void toImageset( const string &strOutput = "" );
private:
int _checkId( char c );
void _processLabel( char *szLabel );
void _processNumber( int num );
void _writeHead();
void _writeBody();
void _writeTail();
void _getName();
protected:
private:
FILE *m_fpIn, *m_fpOut;// 输入输出文件流
string m_strPath;// 输入文件路径
Format m_fmt;// 主体格式
bool m_bString;
bool m_bNumber[4];
int m_nWidth;// 宽度
int m_nHeight;// 高度
string mbAutoScaled;
string m_strName;
string m_strDir;
};
/************************************************************************
* Html2Imageset.cpp
* Author: 陈相礼
* Time: 2010.01.15
* Compiler: VC8
************************************************************************/
#include "Html2Imageset.h"
const string gHead = "<?xml version=/"1.0/" ?>/n";
const string gDecl = "/n";
const string gBody = "/n";
const string gTail = "/n";
bool gbFlag = false;
bool gbSize[4];
//-----------------------------------------------------------------------------
// 构造
Html2Imageset::Html2Imageset( const string &strPath )
{
if ( "" != strPath )
{
m_strPath = strPath;
m_fpIn = m_fpOut = 0;
m_bString = false;
m_bNumber[0] = m_bNumber[1] = m_bNumber[2] = m_bNumber[3] = false;
m_nWidth = 1024;
m_nHeight = 768;
mbAutoScaled = "true";
_getName();
}
}
//-----------------------------------------------------------------------------
// 析构
Html2Imageset::~Html2Imageset()
{
if ( m_fpIn != 0 )
{
fclose( m_fpIn );
m_fpIn = 0;
}
if ( m_fpOut != 0 )
{
fclose( m_fpOut );
m_fpOut = 0;
}
}
//-----------------------------------------------------------------------------
// 转化成Imageset
void Html2Imageset::toImageset( const string &strOutput )
{
m_fpIn = fopen( m_strPath.c_str(), "r" );
if ( "" == strOutput )
{
char szBuffer[256] = "";
sprintf( szBuffer, "%s%s.imageset", m_strDir.c_str(), m_strName.c_str() );
m_fpOut = fopen( szBuffer, "w" );
}
else
{
m_fpOut = fopen( strOutput.c_str(), "w" );
}
if ( !m_fpIn || !m_fpOut )
{
return;
}
_writeHead();
char szBuffer[1024];
while ( !feof( m_fpIn ) )
{
fgets( szBuffer, 1024, m_fpIn );
m_bString = false;
m_bNumber[0] = m_bNumber[1] = m_bNumber[2] = m_bNumber[3] = false;
int nLen = strlen( szBuffer );
for ( int nLoop = 0; nLoop < nLen; ++nLoop )
{
int id = _checkId( szBuffer[nLoop] );
int k = 0;
int t = 0;
char szTmp[128] = "";
switch(id)
{
case 0:continue;break;
case 1:
k = 0;
do
{
if ( k < 128 )
{
szTmp[k++] = szBuffer[nLoop];
}
nLoop++;
id = _checkId(szBuffer[nLoop]);
}while( _checkId( szBuffer[nLoop] ) == 1 || _checkId( szBuffer[nLoop] ) == 2 );
szTmp[k] = '/0';
_processLabel( szTmp );
break;
case 2:
k = 0;
t = 0;
do
{
if( k < 128 )
{
t = szBuffer[nLoop] - '0' + t * 10;
}
nLoop++;
id = _checkId( szBuffer[nLoop] );
}while( _checkId( szBuffer[nLoop] ) == 2 );
_processNumber( t );
break;
default:
break;
}
}
if ( m_bString && m_bNumber[0] && m_bNumber[1] && m_bNumber[2] && m_bNumber[3] )
{
_writeBody();
}
}
_writeTail();
fclose( m_fpIn );
fclose( m_fpOut );
}
//-----------------------------------------------------------------------------
// 字符检测
int Html2Imageset::_checkId( char c )
{
if ( c >= 'a' && c <= 'z'|| c >= 'A' && c <= 'Z' || c == '-' || c == '_' )
return 1;
else if ( c >= '0' && c <= '9' )
return 2;
else return 0;
}
//-----------------------------------------------------------------------------
// 处理标签
void Html2Imageset::_processLabel( char *szLabel )
{
if ( m_bString && gbFlag )
{
strcpy( m_fmt.label, szLabel );
gbFlag = false;
}
if ( !strcmp( szLabel, "id" ) )
{
m_bString = true;
gbFlag = true;
}
else if ( !strcmp( szLabel, "left" ) )
{
m_bNumber[0] = true;
gbSize[0] = true;
}
else if ( !strcmp( szLabel, "top" ) )
{
m_bNumber[1] = true;
gbSize[1] = true;
}
else if ( !strcmp( szLabel, "width" ) )
{
m_bNumber[2] = true;
gbSize[2] = true;
}
else if ( !strcmp( szLabel, "height" ) )
{
m_bNumber[3] = true;
gbSize[3] = true;
}
}
//-----------------------------------------------------------------------------
// 处理数字
void Html2Imageset::_processNumber( int num )
{
if ( m_bNumber[0] && gbSize[0] )
{
m_fmt.xpos = num;
gbSize[0] = false;
}
else if ( m_bNumber[1] && gbSize[1] )
{
m_fmt.ypox = num;
gbSize[1] = false;
}
else if ( m_bNumber[2] && gbSize[2] )
{
m_fmt.width = num;
gbSize[2] = false;
}
else if ( m_bNumber[3] && gbSize[3] )
{
m_fmt.height = num;
gbSize[3] = false;
}
}
//-----------------------------------------------------------------------------
// 写入头部
void Html2Imageset::_writeHead()
{
char szBuffer[256] = "";
sprintf( szBuffer, "%s.png", m_strName.c_str() );
fprintf( m_fpOut, gHead.c_str() );
fprintf( m_fpOut, gDecl.c_str(), m_strName.c_str(), szBuffer, m_nWidth, m_nHeight, mbAutoScaled.c_str() );
}
//-----------------------------------------------------------------------------
// 写入主体
void Html2Imageset::_writeBody()
{
fprintf( m_fpOut, gBody.c_str(), m_fmt.label, m_fmt.xpos, m_fmt.ypox, m_fmt.width, m_fmt.height );
}
//-----------------------------------------------------------------------------
// 写入尾部
void Html2Imageset::_writeTail( )
{
fprintf( m_fpOut, gTail.c_str() );
}
void Html2Imageset::_getName()
{
if ( "" == m_strPath )
{
return;
}
int nSize = m_strPath.size();
int nLoop = 0;
int i = 0;
char szBuffer[256] = "";
char szTmp[256] = "";
strcpy( szBuffer, m_strPath.c_str() );
for ( nLoop = nSize; nLoop > 0; --nLoop )
if ( '/' == szBuffer[nLoop] || '//' == szBuffer[nLoop] ) break;
nLoop++;
for ( i = 0; i < nLoop; ++i )
{
szTmp[i] = szBuffer[i];
}
szTmp[i] = '/0';
m_strDir = szTmp;
for ( i = 0;i < nSize - nLoop; ++i )
{
if ( '.' == szBuffer[nLoop + i] )
{
break;
}
szTmp[i] = szBuffer[nLoop + i];
}
szTmp[i] = '/0';
m_strName = szTmp;
}