#include"CGraphic.h"
#include"../Auxiliary/CString.h"


//	ここのソースには 描画サポート関数を書く

static const float TexelClip = 0.5f;


namespace Maid
{
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! 指定したところを塗りつぶす
/*!
	@param	Pos		[i ]	塗りつぶし開始座標
	@param	Size	[i ]	塗りつぶしの大きさ
	@param	Color	[i ]	塗りつぶす色
 */
void CGraphic::Fill( const POINT2DF& Pos, const SIZE2DF& Size, const COLOR_A08R08G08B08I& Color )
{
	Fill( RECT2DF(Pos, Size), Color );

}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! 指定したところを塗りつぶす
/*!
	@param	rc		[i ]	塗りつぶし範囲
	@param	Color	[i ]	塗りつぶす色
 */
void CGraphic::Fill( const RECT2DF& rc, const COLOR_A08R08G08B08I& Color )
{
	FillSR( rc, SIZE2DF(1,1), 0, VECTOR3DF(0,1,0), POINT2DF(0,0), Color, Color, Color, Color );
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! 指定したところを塗りつぶす
/*!
	@param	Rect	[i ]	塗りつぶし範囲
	@param	Scale	[i ]	拡大率
	@param	Rotate	[i ]	回転
	@param	vec		[i ]	回転軸
	@param	Center	[i ]	基本点
	@param	ColorLT	[i ]	左上頂点の塗りつぶす色
	@param	ColorRT	[i ]	右上頂点の塗りつぶす色
	@param	ColorLB	[i ]	左下頂点の塗りつぶす色
	@param	ColorRB	[i ]	右下頂点の塗りつぶす色
 */
void CGraphic::FillSR  ( const RECT2DF& Rect, const SIZE2DF& Scale, float Rotate, const VECTOR3DF& vec, const POINT2DF& Center, const COLOR_A08R08G08B08I& ColorLT, const COLOR_A08R08G08B08I& ColorRT, const COLOR_A08R08G08B08I& ColorLB, const COLOR_A08R08G08B08I& ColorRB )
{
	const float PosX   = -Center.x* Scale.w;
	const float PosY   = -Center.y* Scale.h;
	const float Width  = Rect.w * Scale.w;
	const float Height = Rect.h * Scale.h;

	RECT2DF Vertex( PosX,       PosY,
					Width, Height );

/*
  参考元：	http://macosx2.ncs.gr.jp/~masa/Articles/Program/matrix3d.html
			http://www.laksmi.co.jp/basic01.html
  任意ベクトルR(Rx, Ry, Rz)を軸としてT回転する行列。

| (1-cosT)*Rx*Rx +    cosT, (1-cosT)*Rx*Ry - Rz*sinT, (1-cosT)*Rx*Rz + Ry*sinT, 0 |
| (1-cosT)*Rx*Ry + Rz*sinT, (1-cosT)*Ry*Ry +    cosT, (1-cosT)*Ry*Rz - Rx*sinT, 0 |
| (1-cosT)*Rx*Rz - Ry*sinT, (1-cosT)*Ry*Rz + Rx*sinT, (1-cosT)*Rz*Rz +    cosT, 0 |
|                        0,                        0,                        0, 1 |

必要なのは 11,21,12,22 の４つ（Ｚ座標は無視する)
なのでそれだけ引っこ抜いて使う

//		fVertex[i].x = ver.x*ans._11 + ver.y*ans._21;
//		fVertex[i].y = ver.x*ans._12 + ver.y*ans._22;

*/

	double cosT = Math<double>::cos(Rotate);
	double sinT = Math<double>::sin(Rotate);


	const double _11 = (1.0-cosT)*vec.x*vec.x +       cosT;
	const double _21 = (1.0-cosT)*vec.x*vec.y + vec.z*sinT;

	const double _12 = (1.0-cosT)*vec.x*vec.y - vec.z*sinT;
	const double _22 = (1.0-cosT)*vec.y*vec.y +       cosT;

	const POINT2DF v[4] =
	{
		POINT2DF( Vertex.GetLT() ),
		POINT2DF( Vertex.GetRT() ),
		POINT2DF( Vertex.GetLB() ),
		POINT2DF( Vertex.GetRB() ),
	};

	const CUSTOMVERTEX_COLOR	Color[] =
	{
		CUSTOMVERTEX_COLOR(POINT3DF(Rect.x+(float32)(v[0].x*_11+v[0].y*_21-TexelClip), Rect.y+(float32)(v[0].x*_12+v[0].y*_22-TexelClip),  0), 1.0f, ColorLT ),
		CUSTOMVERTEX_COLOR(POINT3DF(Rect.x+(float32)(v[1].x*_11+v[1].y*_21-TexelClip), Rect.y+(float32)(v[1].x*_12+v[1].y*_22-TexelClip),  0), 1.0f, ColorRT ),
		CUSTOMVERTEX_COLOR(POINT3DF(Rect.x+(float32)(v[2].x*_11+v[2].y*_21-TexelClip), Rect.y+(float32)(v[2].x*_12+v[2].y*_22-TexelClip),  0), 1.0f, ColorLB ),
		CUSTOMVERTEX_COLOR(POINT3DF(Rect.x+(float32)(v[3].x*_11+v[3].y*_21-TexelClip), Rect.y+(float32)(v[3].x*_12+v[3].y*_22-TexelClip),  0), 1.0f, ColorRB ),
	};


	SetRenderStateZWriteEnable(false);
	SetRenderStateZTestEnable(false);
	SetCullingMode(CULLINGMODE_NONE);
	SetSamplerStateMagFilter( 0, m_FilterType );
	SetSamplerStateMinFilter( 0, m_FilterType );

	UnsetAllTexture();
	SetVertexShader( m_VertexShaderFill[0] );
	SetPixelShader( m_PixelShaderFill[m_BltState] );
	DrawPrimitiveUP( PRIMITIVE_TRIANGLESTRIP, Color, Color[0].GetStructSize(), 2 );
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! テクスチャの矩形描画
/*!
	@param	Pos		[i ]	描画座標
	@param	tex		[i ]	テクスチャ
	@param	rc		[i ]	切り抜きサイズ
	@param	Center	[i ]	中心軸(デフォルトで0,0)
	@param	Alpha	[i ]	透明度(0xFF 見える)
 */
void CGraphic::Blt( const POINT2DF& Pos, const CTexture& tex, const RECT2DI& rc,  const POINT2DF& Center, unt08 Alpha )
{
	const float PosX   = Pos.x - Center.x - TexelClip;
	const float PosY   = Pos.y - Center.y - TexelClip;
	const float Width  = (float)rc.w;
	const float Height = (float)rc.h;

	const SIZE2DF ImageSize = tex.GetTextureSize();

	const RECT2DF tPos( float(rc.x) / ImageSize.w, float(rc.y) / ImageSize.h,
						float(rc.w) / ImageSize.w, float(rc.h) / ImageSize.h );

	COLOR_A08R08G08B08I c(Alpha,0xFF,0xFF,0xFF);

	const CUSTOMVERTEX_SPRITE	Sprite[] =
	{
		CUSTOMVERTEX_SPRITE(POINT3DF(PosX,        PosY,         0), 1.0f, c, tPos.GetLT() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(PosX+Width,  PosY,         0), 1.0f, c, tPos.GetRT() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(PosX,        PosY+Height,  0), 1.0f, c, tPos.GetLB() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(PosX+Width,  PosY+Height,  0), 1.0f, c, tPos.GetRB() ),
	};

	SetRenderStateZWriteEnable(false);
	SetRenderStateZTestEnable(false);
	SetCullingMode(CULLINGMODE_NONE);
	SetSamplerStateMagFilter( 0, m_FilterType );
	SetSamplerStateMinFilter( 0, m_FilterType );

	UnsetAllTexture();
	SetTexture( tex );
	SetVertexShader( m_VertexShaderBlt[0] );
	SetPixelShader( m_PixelShaderBlt[m_BltState] );
	DrawPrimitiveUP( PRIMITIVE_TRIANGLESTRIP, Sprite, Sprite[0].GetStructSize(), 2 );
}



void CGraphic::BltS ( const POINT2DF& Pos, const CTexture& tex, const RECT2DI& rc, const SIZE2DF& Scale, const POINT2DF& Center, unt08 Alpha )
{
	const float PosX   = Pos.x - Center.x * Scale.w - TexelClip;
	const float PosY   = Pos.y - Center.y * Scale.h - TexelClip;
	const float Width  = (float)rc.w * Scale.w;
	const float Height = (float)rc.h * Scale.h;

	const SIZE2DF TexSize = tex.GetTextureSize();

	const RECT2DF tPos( float(rc.x) / TexSize.w, float(rc.y) / TexSize.h,
						float(rc.w) / TexSize.w, float(rc.h) / TexSize.h );

	COLOR_A08R08G08B08I c(Alpha,0xFF,0xFF,0xFF);

	const CUSTOMVERTEX_SPRITE	Sprite[] =
	{
		CUSTOMVERTEX_SPRITE(POINT3DF(PosX,        PosY,         0), 1.0f, c, tPos.GetLT() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(PosX+Width,  PosY,         0), 1.0f, c, tPos.GetRT() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(PosX,        PosY+Height,  0), 1.0f, c, tPos.GetLB() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(PosX+Width,  PosY+Height,  0), 1.0f, c, tPos.GetRB() ),
	};

	SetRenderStateZWriteEnable(false);
	SetRenderStateZTestEnable(false);
	SetCullingMode(CULLINGMODE_NONE);
	SetSamplerStateMagFilter( 0, m_FilterType );
	SetSamplerStateMinFilter( 0, m_FilterType );

	UnsetAllTexture();
	SetTexture( tex );
	SetVertexShader( m_VertexShaderBlt[0] );
	SetPixelShader( m_PixelShaderBlt[m_BltState] );
	DrawPrimitiveUP( PRIMITIVE_TRIANGLESTRIP, Sprite, Sprite[0].GetStructSize(), 2 );

}

void CGraphic::BltR ( const POINT2DF& Pos, const CTexture& tex, const RECT2DI& rc, float Rotate, const VECTOR3DF& vec, const POINT2DF& Center, unt08 Alpha )
{
	const SIZE2DF TexSize = tex.GetTextureSize();

	const RECT2DF tPos( float(rc.x) / TexSize.w, float(rc.y) / TexSize.h,
						float(rc.w) / TexSize.w, float(rc.h) / TexSize.h );

	RECT2DF Vertex( -Center.x, -Center.y,   float(rc.w), float(rc.h) );


/*
　任意ベクトルR(Rx, Ry, Rz)を軸としてT回転する行列。

| (1-cosT)*Rx*Rx +    cosT, (1-cosT)*Rx*Ry + Rz*sinT, (1-cosT)*Rx*Rz - Ry*sinT, 0 |
| (1-cosT)*Rx*Ry - Rz*sinT, (1-cosT)*Ry*Ry +    cosT, (1-cosT)*Ry*Rz + Rx*sinT, 0 |
| (1-cosT)*Rx*Rz + Ry*sinT, (1-cosT)*Ry*Rz - Rx*sinT, (1-cosT)*Rz*Rz +    cosT, 0 |
|                        0,                        0,                        0, 1 |

必要なのは 11,21,12,22 の４つ（Ｚ座標は無視する)
なのでそれだけ引っこ抜いて使う

//		fVertex[i].x = ver.x*ans._11 + ver.y*ans._21;
//		fVertex[i].y = ver.x*ans._12 + ver.y*ans._22;

*/
	const float cosT = Math<float>::cos(Rotate);
	const float sinT = Math<float>::sin(Rotate);


	const float _11 = (1.0f-cosT)*vec.x*vec.x +       cosT;
	const float _12 = (1.0f-cosT)*vec.x*vec.y + vec.z*sinT;
	const float _13 = (1.0f-cosT)*vec.x*vec.z - vec.y*sinT;

	const float _21 = (1.0f-cosT)*vec.x*vec.y - vec.z*sinT;
	const float _22 = (1.0f-cosT)*vec.y*vec.y +       cosT;
	const float _23 = (1.0f-cosT)*vec.y*vec.z + vec.x*sinT;


	const POINT2DF v[4] =
	{
		POINT2DF( Vertex.x         *_11+Vertex.y          *_12, Vertex.x         *_21+Vertex.y          *_22 ),
		POINT2DF( Vertex.GetRight()*_11+Vertex.y          *_12, Vertex.GetRight()*_21+Vertex.y          *_22 ),
		POINT2DF( Vertex.x         *_11+Vertex.GetBottom()*_12, Vertex.x         *_21+Vertex.GetBottom()*_22 ),
		POINT2DF( Vertex.GetRight()*_11+Vertex.GetBottom()*_12, Vertex.GetRight()*_21+Vertex.GetBottom()*_22 ),
	};

	COLOR_A08R08G08B08I c(Alpha,0xFF,0xFF,0xFF);

	const CUSTOMVERTEX_SPRITE	Sprite[] =
	{
		CUSTOMVERTEX_SPRITE(POINT3DF(Pos.x+v[0].x-TexelClip, Pos.y+v[0].y-TexelClip,  0), 1.0f, c, tPos.GetLT() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(Pos.x+v[1].x-TexelClip, Pos.y+v[1].y-TexelClip,  0), 1.0f, c, tPos.GetRT() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(Pos.x+v[2].x-TexelClip, Pos.y+v[2].y-TexelClip,  0), 1.0f, c, tPos.GetLB() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(Pos.x+v[3].x-TexelClip, Pos.y+v[3].y-TexelClip,  0), 1.0f, c, tPos.GetRB() ),
	};

	SetRenderStateZWriteEnable(false);
	SetRenderStateZTestEnable(false);
	SetCullingMode(CULLINGMODE_NONE);
	SetSamplerStateMagFilter( 0, m_FilterType );
	SetSamplerStateMinFilter( 0, m_FilterType );

	UnsetAllTexture();
	SetTexture( tex );
	SetVertexShader( m_VertexShaderBlt[0] );
	SetPixelShader( m_PixelShaderBlt[m_BltState] );
	DrawPrimitiveUP( PRIMITIVE_TRIANGLESTRIP, Sprite, Sprite[0].GetStructSize(), 2 );

}

void CGraphic::BltSR( const POINT2DF& Pos, const CTexture& tex, const RECT2DI& rc, const SIZE2DF& Scale, float Rotate, const VECTOR3DF& vec, const POINT2DF& Center, unt08 Alpha )
{
	const float PosX   = -Center.x* Scale.w;
	const float PosY   = -Center.y* Scale.h;
	const float Width  = rc.w * Scale.w;
	const float Height = rc.h * Scale.h;

	const SIZE2DF TexSize = tex.GetTextureSize();

	const RECT2DF tPos( float(rc.x) / TexSize.w, float(rc.y) / TexSize.h,
						float(rc.w) / TexSize.w, float(rc.h) / TexSize.h );

	RECT2DF Vertex( PosX,       PosY,
				    Width, Height );

/*
　任意ベクトルR(Rx, Ry, Rz)を軸としてT回転する行列。

| (1-cosT)*Rx*Rx +    cosT, (1-cosT)*Rx*Ry + Rz*sinT, (1-cosT)*Rx*Rz - Ry*sinT, 0 |
| (1-cosT)*Rx*Ry - Rz*sinT, (1-cosT)*Ry*Ry +    cosT, (1-cosT)*Ry*Rz + Rx*sinT, 0 |
| (1-cosT)*Rx*Rz + Ry*sinT, (1-cosT)*Ry*Rz - Rx*sinT, (1-cosT)*Rz*Rz +    cosT, 0 |
|                        0,                        0,                        0, 1 |


必要なのは 11,21,12,22 の４つ（Ｚ座標は無視する)
なのでそれだけ引っこ抜いて使う

//		fVertex[i].x = ver.x*ans._11 + ver.y*ans._21;
//		fVertex[i].y = ver.x*ans._12 + ver.y*ans._22;

*/
	const float cosT = Math<float>::cos(Rotate);
	const float sinT = Math<float>::sin(Rotate);

	const float _11 = (1.0f-cosT)*vec.x*vec.x +       cosT;
	const float _12 = (1.0f-cosT)*vec.x*vec.y + vec.z*sinT;
	const float _13 = (1.0f-cosT)*vec.x*vec.z - vec.y*sinT;

	const float _21 = (1.0f-cosT)*vec.x*vec.y - vec.z*sinT;
	const float _22 = (1.0f-cosT)*vec.y*vec.y +       cosT;
	const float _23 = (1.0f-cosT)*vec.y*vec.z + vec.x*sinT;


	const POINT2DF v[4] =
	{
		POINT2DF( Vertex.x         *_11+Vertex.y          *_12, Vertex.x         *_21+Vertex.y          *_22 ),
		POINT2DF( Vertex.GetRight()*_11+Vertex.y          *_12, Vertex.GetRight()*_21+Vertex.y          *_22 ),
		POINT2DF( Vertex.x         *_11+Vertex.GetBottom()*_12, Vertex.x         *_21+Vertex.GetBottom()*_22 ),
		POINT2DF( Vertex.GetRight()*_11+Vertex.GetBottom()*_12, Vertex.GetRight()*_21+Vertex.GetBottom()*_22 ),
	};

	COLOR_A08R08G08B08I c(Alpha,0xFF,0xFF,0xFF);

	const CUSTOMVERTEX_SPRITE	Sprite[] =
	{
		CUSTOMVERTEX_SPRITE(POINT3DF(Pos.x+v[0].x-TexelClip, Pos.y+v[0].y-TexelClip,  0), 1.0f, c, tPos.GetLT() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(Pos.x+v[1].x-TexelClip, Pos.y+v[1].y-TexelClip,  0), 1.0f, c, tPos.GetRT() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(Pos.x+v[2].x-TexelClip, Pos.y+v[2].y-TexelClip,  0), 1.0f, c, tPos.GetLB() ),
		CUSTOMVERTEX_SPRITE(POINT3DF(Pos.x+v[3].x-TexelClip, Pos.y+v[3].y-TexelClip,  0), 1.0f, c, tPos.GetRB() ),
	};

	SetRenderStateZWriteEnable(false);
	SetRenderStateZTestEnable(false);
	SetCullingMode(CULLINGMODE_NONE);
	SetSamplerStateMagFilter( 0, m_FilterType );
	SetSamplerStateMinFilter( 0, m_FilterType );

	UnsetAllTexture();
	SetTexture( tex );
	SetVertexShader( m_VertexShaderBlt[0] );
	SetPixelShader( m_PixelShaderBlt[m_BltState] );
	DrawPrimitiveUP( PRIMITIVE_TRIANGLESTRIP, Sprite, Sprite[0].GetStructSize(), 2 );
}
















/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! テキスト描画
/*!
 	@\n による改行もサポートしています 
 
 	@param	Pos			[i ]	転送先座標(この座標から右側に描画されていく）
 	@param	pFont		[i ]	描画に使うフォント
 	@param	Color		[i ]	テキストの色・不透明度
 	@param	Text		[i ]	描画する文字列
 	@param	StrCount	[i ]	描画する文字数 負数 で全部。2BYTE文字も１文字と数えます、ただし\\nは１文字と数えません
 	@param	eDir		[i ]	描画する方向
 */
void CGraphic::BltText( const POINT2DF& Pos, const SPFONT& pFont, const COLOR_A08R08G08B08I& Color, const mstring& Text, int StrCount, TEXTDIRECTION eDir )
{
	//	空文字だったら描画しない
	if( Text.empty() ) { return ; }

	const float DrawX = Pos.x-0.5f;
	const float DrawY = Pos.y-0.5f;

	const float DrawW = (float)pFont->GetSize().w;
	const float DrawH = (float)pFont->GetSize().h;


	int TextLineLength =0;	//	１行の最大文字数(1byteCode が +1 2byteCode は+2)
	int DrawTextCount;		//	引数 Text から実際に何文字描画するか？


	{	//	描画する文字数を求める
		int	CountCF=0;	// '\n' が何個あるか？
		int	NowStrCount=0;	//	現在行の文字数(1byteCode が +1 2byteCode は+2)

		for( int i=0; i<(int)Text.length(); ++i )
		{
			const unt32 c = Text[i];

			if( !CString::IsHankaku(c) )
			{
				NowStrCount += 2;
			}else
			{
				if( c=='\r' ) { continue; }
				ef( c=='\t' ) { continue; }
				ef( c=='\n' ) 
				{
					TextLineLength = max( TextLineLength, NowStrCount );
					CountCF++; 
					NowStrCount = 0;
				}else
				{
					NowStrCount += 1;
				}
			}
		}
		TextLineLength = max( TextLineLength, NowStrCount );

		{	//	引数からクリップする
			if( StrCount<0 ) { DrawTextCount = (unt32)Text.size(); }
			else			 { DrawTextCount = StrCount+CountCF; }
		}
	}


	POINT2DF LinePos;	//	１ラインの描画開始座標
	POINT2DF DeltaPos;	//	進行座標
	{	//	eDir から初期座標を修正する

		switch( eDir )
		{
		case TEXTDIRECTION_LEFT: 
			{
				LinePos.x = DrawX;
				LinePos.y = DrawY;
				DeltaPos.x= 1;
				DeltaPos.y= 0;
			}break;

		case TEXTDIRECTION_RIGHT:
			{
				LinePos.x = DrawX - (float)(TextLineLength)*DrawW;
				LinePos.y = DrawY;
				DeltaPos.x= 1;
				DeltaPos.y= 0;
			}break;

		case TEXTDIRECTION_TOP:
			{
				LinePos.x = DrawX- DrawW*2;
				LinePos.y = DrawY;
				DeltaPos.x= 0;
				DeltaPos.y= 1;
			}break;

		case TEXTDIRECTION_BOTTOM:
			{
				LinePos.x = DrawX - DrawW*2;
				LinePos.y = DrawY - (float)(TextLineLength-1)*DrawH;
				DeltaPos.x= 0;
				DeltaPos.y= 1;
			}break;
		}
	}

	POINT2DF DrawPos = LinePos;	//	現在の描画開始座標
	UnsetAllTexture();
	SetVertexShader( m_VertexShaderBlt[0] );
	SetPixelShader( m_PixelShaderFont[0] );
	{
		for( int i=0; i<DrawTextCount; ++i )
		{
			const unt32 Code = Text[i];
			const float WIDTH  = CString::IsHankaku(Code)? DrawW : DrawW*2;
			const float HEIGHT = DrawH;

			if( Code=='\n' )
			{	//	改行コードだったら次の行に移動してリセット
				switch( eDir )
				{
				case TEXTDIRECTION_LEFT:
				case TEXTDIRECTION_RIGHT:  { LinePos.y += HEIGHT; }break;
				case TEXTDIRECTION_TOP:
				case TEXTDIRECTION_BOTTOM: { LinePos.x -= DrawW*2; }break; // 全部 1byte文字だったら１行空いてしまうね。
				}
				DrawPos = LinePos;
				continue;
			}
			ef( Code=='\t' ) { continue; }	//	タブは除外

			const CTexture& tex = GetFont( pFont, Code );


			{
				const SIZE2DF rc = tex.GetSize();
				const SIZE2DF TexSize = tex.GetTextureSize();

				const RECT2DF tPos( float(   0) / TexSize.w, float(   0) / TexSize.h,
									float(rc.w) / TexSize.w, float(rc.h) / TexSize.h );

				const RECT2DF vPos( DrawPos, SIZE2DF(WIDTH,HEIGHT) );

				const CUSTOMVERTEX_SPRITE	Sprite[] =
				{
					CUSTOMVERTEX_SPRITE( POINT3DF(DrawPos.x,      DrawPos.y,       0), 1.0f, Color, tPos.GetLT() ),
					CUSTOMVERTEX_SPRITE( POINT3DF(DrawPos.x+WIDTH,DrawPos.y,       0), 1.0f, Color, tPos.GetRT() ),
					CUSTOMVERTEX_SPRITE( POINT3DF(DrawPos.x,      DrawPos.y+HEIGHT,0), 1.0f, Color, tPos.GetLB() ),
					CUSTOMVERTEX_SPRITE( POINT3DF(DrawPos.x+WIDTH,DrawPos.y+HEIGHT,0), 1.0f, Color, tPos.GetRB() ),
				};

				SetTexture( tex );
				DrawPrimitiveUP( PRIMITIVE_TRIANGLESTRIP, Sprite, Sprite[0].GetStructSize(), 2 );
			}
		
			DrawPos.x += WIDTH *DeltaPos.x;
			DrawPos.y += HEIGHT*DeltaPos.y;
		}
	}
}

const CTexture&	CGraphic::GetFont( const SPFONT& pFont, unt32 Code )
{
	GAIZIMAP::iterator ite = m_GaiziMap.find(Code);

	if( ite!=m_GaiziMap.end() ) { return ite->second; }

	return m_FontCache.GetCache( pFont, Code );
}

void CGraphic::AddGaizi( unt32 no, const CTextureFile& tex )
{
	m_GaiziMap[no] = tex;
}



/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! テキスト数値描画
/*!
 	@param	Pos		[i ]	転送先座標
 	@param	Src		[i ]	描画に使うテクスチャ
 	@param	pRect	[i ]	数字データのRECT 0123456789- の順に並ぶ
 	@param	Number	[i ]	描画する値
 	@param	Len		[i ]	描画する桁数
 	@param	dir		[i ]	描画する方向
 */
void CGraphic::BltNumber( const POINT2DF& Pos, const CTexture& Src, const RECT2DI* pRect, int Number, int Len, TEXTDIRECTION dir )
{
	MySTL::vector<int>	ValueList;


	//	値を１桁ごとの配列に切り分ける
	{
		int num = Number;

		if( Len==-1 )
		{
			while( true )
			{
				const int v = num % 10;
				num /= 10;

				ValueList.push_back( v );

				if( num==0 ) { break; }
			}
		}else
		{
			for( int i=0; i<Len; ++i )
			{
				if( num==0 )
				{
					for( ; i<Len; ++i )
					{
						ValueList.push_back(0);
					}
					break; 
				}

				const int v = num % 10;
				num /= 10;

				ValueList.push_back( v );
			}

		}

		if( Number<0 ) { ValueList.push_back(10); }
	}

	POINT2DF BasePos;

	switch( dir )
	{
	case TEXTDIRECTION_LEFT: { BasePos = Pos; }break;
	case TEXTDIRECTION_RIGHT:
		{
			int width = 0;

			for( int i=0; i<(int)ValueList.size(); ++i )
			{
				width += pRect[ValueList[i]].w;
			}
			BasePos.x = Pos.x - width;
			BasePos.y = Pos.y;
		}break;
	}


	POINT2DF p = BasePos;
	for( int i=0; i<(int)ValueList.size(); ++i )
	{
		const RECT2DI& rc = pRect[ValueList[ValueList.size()-1-i]];
		Blt( p, Src, rc );

		p.x += rc.w;
	}
}

}