/*************************************************************************************************/
/*!
   	@file		GraphicsCmd.h
	@author 	Fanzo
*/
/*************************************************************************************************/
#pragma		once

///////////////////////////////////////////////////////////////////////////////////////////////////
//include files


#pragma pack( push , 8 )		//set align

namespace icubic
{

///////////////////////////////////////////////////////////////////////////////////////////////////
// preprocessor deifne

///////////////////////////////////////////////////////////////////////////////////////////////////
// type define

enum PaintUnit
{
	ViewSpace_PaintUnit , 
	BoundBox_PaintUnit , 
};

///////////////////////////////////////////////////////////////////////////////////////////////////
// interface define
/**************************************************************************************************
 "IPaint_ipr" interface 
***************************************************************************************************/
cb_guid_define( IPaint_ipr_IID , 0x945628A6 , 0x45FC4173 , 0xB743BC4C , 0x44CD24C6 );
class IPaint_ipr;
typedef icubic::iface_object< IPaint_ipr , IPaint_ipr_IID >		iPaint_ipr;
typedef icubic::iface_reference< IPaint_ipr , IPaint_ipr_IID >	rPaint_ipr;
///////////////////////////////////////////////////////////////////////////////////////////////////
class IPaint_ipr : public IPaint
{
public:
//=================================================================================================
//!	set parameter
//!	@retval			---
//-------------------------------------------------------------------------------------------------
virtual
void cb_call SetParameter
		(
		const Coord_view&	view , 
		const frect&		boundbox , 
		const faffine&		trans
		) = 0;
};
/**************************************************************************************************
 "IPen_ipr" interface 
***************************************************************************************************/
cb_guid_define( IPen_ipr_IID , 0xA361C598 , 0xCE884033 , 0xBA52263A , 0x4A05DE76 );
class IPen_ipr;
typedef icubic::iface_object< IPen_ipr , IPen_ipr_IID >		iPen_ipr;
typedef icubic::iface_reference< IPen_ipr , IPen_ipr_IID >	rPen_ipr;
///////////////////////////////////////////////////////////////////////////////////////////////////
class IPen_ipr : public IOutlineGen
{
public:
//=================================================================================================
//!	set parameter
//!	@retval			---
//-------------------------------------------------------------------------------------------------
virtual
void cb_call SetParameter
		(
		const Coord_view&	view
		) = 0;
};
/**************************************************************************************************
 "IClip_clipcmd" interface 
***************************************************************************************************/
cb_guid_define( IClip_clipcmd_IID , 0x78E4FBF8 , 0xA0394c5d , 0xA9A54F79 , 0xE8A582AB );
class IClip_clipcmd;
typedef icubic::iface_object< IClip_clipcmd , IClip_clipcmd_IID >		iClip_clipcmd;
typedef icubic::iface_reference< IClip_clipcmd , IClip_clipcmd_IID >	rClip_clipcmd;
///////////////////////////////////////////////////////////////////////////////////////////////////
class IClip_clipcmd
{
public:
//=================================================================================================
//!	get clip
//!	@retval			---
//-------------------------------------------------------------------------------------------------
virtual
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		) = 0;
};
/**************************************************************************************************
 "IClip_clipcmds" interface 
***************************************************************************************************/
cb_guid_define( IClip_clipcmds_IID , 0x16013C52 , 0xD1124558 , 0xBC933D0D , 0x91B1A2F3 );
class IClip_clipcmds;
typedef icubic::iface_object< IClip_clipcmds , IClip_clipcmds_IID >		iClip_clipcmds;
typedef icubic::iface_reference< IClip_clipcmds , IClip_clipcmds_IID >	rClip_clipcmds;
///////////////////////////////////////////////////////////////////////////////////////////////////
class IClip_clipcmds : public IClip_clipcmd
{
public:
//=================================================================================================
//!	add clip
//!	@retval			---
//-------------------------------------------------------------------------------------------------
virtual
void AddCmd
		(
		iClip_clipcmd&		cmd
		) = 0;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// classes define

//=================================================================================================
cb_inline
float VtoP_x
		(
		const DPI&			dpi , 
		const frect&		view , 
		const value_ipr&	v
		)
{
	if( v.m_unit == value_ipr::inch )
		return dpi.ItoD_x( v.m_value );
	else if( v.m_unit == value_ipr::ratio )
		return v.m_value * view.Width() + view.xmin;
	else
		return v.m_value;
}
//=================================================================================================
cb_inline
float VtoP_y
		(
		const DPI&			dpi , 
		const frect&		view , 
		const value_ipr&	v
		)
{
	if( v.m_unit == value_ipr::inch )
		return dpi.ItoD_y( v.m_value );
	else if( v.m_unit == value_ipr::ratio )
		return v.m_value * view.Height() + view.ymin;
	else
		return v.m_value;
}
//=================================================================================================
cb_inline
float VtoP_l
		(
		const DPI&			dpi , 
		const frect&		view , 
		const value_ipr&	v
		)
{
	if( v.m_unit == value_ipr::inch )
		return max( dpi.ItoD_x( v.m_value ) , dpi.ItoD_y( v.m_value ) );
	else if( v.m_unit == value_ipr::ratio )
		return v.m_value * max( view.Width() , view.Height() );
	else
		return v.m_value;
}
//=================================================================================================
cb_inline
float VtoP_w
		(
		const DPI&			dpi , 
		const frect&		view , 
		const value_ipr&	v
		)
{
	if( v.m_unit == value_ipr::inch )
		return max( dpi.ItoD_x( v.m_value ) , dpi.ItoD_y( v.m_value ) );
	else if( v.m_unit == value_ipr::ratio )
		return v.m_value * view.Width();
	else
		return v.m_value;
}
//=================================================================================================
cb_inline
float VtoP_h
		(
		const DPI&			dpi , 
		const frect&		view , 
		const value_ipr&	v
		)
{
	if( v.m_unit == value_ipr::inch )
		return max( dpi.ItoD_x( v.m_value ) , dpi.ItoD_y( v.m_value ) );
	else if( v.m_unit == value_ipr::ratio )
		return v.m_value * view.Height();
	else
		return v.m_value;
}
//=================================================================================================
cb_inline
fvector2 VtoP
		(
		const DPI&			dpi , 
		const frect&		view , 
		const point_ipr&	v
		)
{
	return fvector2( VtoP_x( dpi , view , v.x ) , VtoP_y( dpi , view , v.y ) );
}
//=================================================================================================
cb_inline
frect VtoP
		(
		const DPI&			dpi , 
		const frect&		view , 
		const rect_ipr&		v
		)
{
	return frect( VtoP_x( dpi , view , v.x ) , VtoP_y( dpi , view , v.y ) , VtoP_x( dpi , view , v.x ) + VtoP_x( dpi , view , v.w ) , VtoP_y( dpi , view , v.y ) + VtoP_y( dpi , view , v.h ) ).Normalize(); 
}
//=================================================================================================
cb_inline
float VtoP_x
		(
		PaintUnit			unit , 
		const DPI&			dpi , 
		const frect&		view , 
		const frect&		boundbox , 
		const value_ipr&	v
		)
{
	if( unit == ViewSpace_PaintUnit )
		return VtoP_x( dpi , view , v );

	if( v.m_unit == value_ipr::inch )
		return dpi.ItoD_x( v.m_value ) + boundbox.xmin;
	else if( v.m_unit == value_ipr::ratio )
		return v.m_value * boundbox.Width() + boundbox.xmin;
	else
		return v.m_value + boundbox.xmin;
}
//=================================================================================================
cb_inline
float VtoP_y
		(
		PaintUnit			unit , 
		const DPI&			dpi , 
		const frect&		view , 
		const frect&		boundbox , 
		const value_ipr&	v
		)
{
	if( unit == ViewSpace_PaintUnit )
		return VtoP_y( dpi , view , v );

	if( v.m_unit == value_ipr::inch )
		return dpi.ItoD_y( v.m_value ) + boundbox.ymin;
	else if( v.m_unit == value_ipr::ratio )
		return v.m_value * boundbox.Height() + boundbox.ymin;
	else
		return v.m_value + boundbox.ymin;
}
//=================================================================================================
cb_inline
float VtoP_l
		(
		PaintUnit			unit , 
		const DPI&			dpi , 
		const frect&		view , 
		const frect&		boundbox , 
		const value_ipr&	v
		)
{
	if( unit == ViewSpace_PaintUnit )
		return VtoP_l( dpi , view , v );

	if( v.m_unit == value_ipr::inch )
		return max( dpi.ItoD_x( v.m_value ) , dpi.ItoD_y( v.m_value ) );
	else if( v.m_unit == value_ipr::ratio )
		return v.m_value * max( boundbox.Width() , boundbox.Height() );
	else
		return v.m_value;
}
//=================================================================================================
cb_inline
fvector2 VtoP
		(
		PaintUnit			unit , 
		const DPI&			dpi , 
		const frect&		view , 
		const frect&		boundbox , 
		const point_ipr&	v
		)
{
	return fvector2( VtoP_x( unit , dpi , view , boundbox , v.x ) , VtoP_y( unit , dpi , view , boundbox , v.y ) );
}
//=================================================================================================
cb_inline
frect VtoP
		(
		PaintUnit			unit , 
		const DPI&			dpi , 
		const frect&		view , 
		const frect&		boundbox , 
		const rect_ipr&		v
		)
{
	return frect
			( 
			VtoP_x( unit , dpi , view , boundbox , v.x ) , 
			VtoP_y( unit , dpi , view , boundbox , v.y ) , 
			VtoP_x( unit , dpi , view , boundbox , v.x ) + VtoP_x( unit , dpi , view , boundbox , v.w ) ,
			VtoP_y( unit , dpi , view , boundbox , v.y ) + VtoP_y( unit , dpi , view , boundbox , v.h ) 
			).Normalize(); 
}

//=================================================================================================
cb_inline
float VtoP_x
		(
		const DPI&		dpi , 
		const value_ip&	v
		)
{
	if( v.m_unit == value_ip::inch )
		return dpi.ItoD_x( v.m_value );
	else
		return v.m_value;
}
//=================================================================================================
cb_inline
float VtoP_y
		(
		const DPI&		dpi , 
		const value_ip&	v
		)
{
	if( v.m_unit == value_ip::inch )
		return dpi.ItoD_y( v.m_value );
	else
		return v.m_value;
}
//=================================================================================================
cb_inline
float VtoP_l
		(
		const DPI&		dpi , 
		const value_ip&	v
		)
{
	if( v.m_unit == value_ip::inch )
		return max( dpi.ItoD_x( v.m_value ) , dpi.ItoD_y( v.m_value ) );
	else
		return v.m_value;
}
//=================================================================================================
cb_inline
fvector2 VtoP
		(
		const DPI&		dpi , 
		const point_ip&	v
		)
{
	return fvector2( VtoP_x( dpi , v.x ) , VtoP_y( dpi , v.y ) );
}
//=================================================================================================
cb_inline
float GetSampleScale
		(
		const faffine&  tod
		)
{
	return (tod.Transform( fvector2( 1.0f , 1.0f ) ) - tod.Transform( fvector2( 0.0f , 0.0f ) )).Length();
}
//=================================================================================================
cb_inline
void CreateTextPath
		(
		iPath&				path , 
		const wchar_t*		str , 
		int					length , 
		iFont&				font
		)
{
	path->Reset();
	float		h	= font->GetCharHeight();
	fvector2	p( 0.0f , 0.0f );
	const wchar_t*	s	= str;
	int				off , l = 0;
	for( off = 0 ; off < length ; off++ )
	{
		if( str[ off ] == L'\n' || off == length - 1 )
		{
			if( str[ off ] != L'\n' )
				l++;
			font->CreateStringPath( path , s , l , faffine::GetMove( p ) );
			s	= str + off + 1;
			l	= 0;
			p.y += h;
		}
		else
			l++;
	}
}
/**************************************************************************************************
"PaintSolidColor_ipr" class 
**************************************************************************************************/
class PaintSolidColor_ipr : 
	public PaintSolidColor_bs<IPaint_ipr> , 
	virtual public object_base
{
// query
	query_begin()
	iface_hook( IPaint , IPaint_IID )
	iface_hook( IPaint_ipr , IPaint_ipr_IID )
	query_end( object_base )
	
// variable member
private:
	
// "IPaint_ipr" interface functions
public:
//=================================================================================================
void cb_call SetParameter
		(
		const Coord_view&	view , 
		const frect&		boundbox , 
		const faffine&		trans
		)
{
}
};
/**************************************************************************************************
"PaintGradLinear_ipr" class 
**************************************************************************************************/
class PaintGradLinear_ipr : 
	protected PaintGradLinear_bs<IPaint_ipr> , 
	virtual public object_base
{
// query
	query_begin()
	iface_hook( IPaint , IPaint_IID )
	iface_hook( IPaint_ipr , IPaint_ipr_IID )
	query_end( object_base )
	
// variable member
private:
	PaintUnit		m_paint_unit;
	point_ipr		m_start_pos;
	point_ipr		m_target_pos;
	Array<float>	m_rate;
	Array<rgba>		m_color;
	faffine			m_transform;
	
// "IPaint_ipr" interface functions
public:
//=================================================================================================
void cb_call SetParameter
		(
		const Coord_view&		view , 
		const frect&			boundbox , 
		const faffine&			trans
		)
{
	DPI		dpi	= view.GetDPI();
	frect	v	= view.GetView();
	PaintGradLinear_bs<IPaint_ipr>::SetGradationVector( VtoP( m_paint_unit , dpi , v , boundbox , m_start_pos ) , VtoP( m_paint_unit , dpi , v , boundbox , m_target_pos ) );
	PaintGradLinear_bs<IPaint_ipr>::SetTransform( view.GetVtoD() * trans * m_transform );
	PaintGradLinear_bs<IPaint_ipr>::SetColorTable( m_rate.GetDatanum() , m_rate.GetConstPtr() , m_color.GetConstPtr() );
}
// "public" functions
public:
//=================================================================================================
PaintGradLinear_ipr() : m_paint_unit( BoundBox_PaintUnit )
{
}
//=================================================================================================
void SetPaintUnit
		(
		PaintUnit	paintunit
		)
{
	m_paint_unit	= paintunit;
}
//=================================================================================================
void SetTransform
		(
		const faffine&	transform
		)
{
	m_transform	= transform;
}
//=================================================================================================
void SetGradationVector
		(
		const point_ipr&	start , 
		const point_ipr&	target
		)
{
	m_start_pos		= start;
	m_target_pos	= target;
}
//=================================================================================================
void cb_call SetColorTable
		(
		int			num , 
		const float	rate[] ,		//!< [in] it need to be 0.0 - 1.0
		const rgba	color[]
		)
{
	m_rate.Resize( num );
	m_color.Resize( num );
	int		off;
	for( off = 0 ; off < num ; off++ )
	{
		m_rate[off]	= rate[off];
		m_color[off]= color[off];
	}
}
};
/**************************************************************************************************
"PaintGradRadial_ipr" class 
**************************************************************************************************/
class PaintGradRadial_ipr : 
	public PaintGradRadial_bs<IPaint_ipr> , 
	virtual public object_base
{
// query
	query_begin()
	iface_hook( IPaint , IPaint_IID )
	iface_hook( IPaint_ipr , IPaint_ipr_IID )
	query_end( object_base )
	
// variable member
private:
	PaintUnit		m_paint_unit;
	point_ipr		m_center_pos;
	value_ipr		m_radius;
	Array<float>	m_rate;
	Array<rgba>		m_color;
	faffine			m_transform;
	
// "IPaint_ipr" interface functions
public:
//=================================================================================================
void cb_call SetParameter
		(
		const Coord_view&	view , 
		const frect&		boundbox , 
		const faffine&		trans
		)
{
	DPI		dpi	= view.GetDPI();
	frect	v	= view.GetView();
	PaintGradRadial_bs<IPaint_ipr>::SetGradationVector( VtoP( m_paint_unit , dpi , v , boundbox , m_center_pos ) , VtoP_l( m_paint_unit , dpi , v , boundbox , m_radius ) );
	PaintGradRadial_bs<IPaint_ipr>::SetTransform( view.GetVtoD() * trans * m_transform );
	PaintGradRadial_bs<IPaint_ipr>::SetColorTable( m_rate.GetDatanum() , m_rate.GetConstPtr() , m_color.GetConstPtr() );
}
// "public" functions
public:
//=================================================================================================
PaintGradRadial_ipr() : m_paint_unit( BoundBox_PaintUnit )
{
}
//=================================================================================================
void SetPaintUnit
		(
		PaintUnit	paintunit
		)
{
	m_paint_unit	= paintunit;
}
//=================================================================================================
void SetTransform
		(
		const faffine&	transform
		)
{
	m_transform	= transform;
}
//=================================================================================================
void SetGradationVector
		(
		const point_ipr&	center , 
		const value_ipr&	radius
		)
{
	m_center_pos	= center;
	m_radius		= radius;
}
//=================================================================================================
void cb_call SetColorTable
		(
		int			num , 
		const float	rate[] ,		//!< [in] it need to be 0.0 - 1.0
		const rgba	color[]
		)
{
	m_rate.Resize( num );
	m_color.Resize( num );

	int		off;
	for( off = 0 ; off < num ; off++ )
	{
		m_rate[off]	= rate[off];
		m_color[off]= color[off];
	}
}
};
/**************************************************************************************************
"Pen_ipr" class 
**************************************************************************************************/
class Pen_ipr : 
	public OutlineGenStroke_bs<IPen_ipr> , 
	virtual public object_base
{
// query
	query_begin()
	iface_hook( IOutlineGen , IOutlineGen_IID )
	iface_hook( IPen_ipr , IPen_ipr_IID )
	query_end( object_base )
	
// variable member
private:
	value_ipr	m_width;
	
// "IPaint_ipr" interface functions
public:
//=================================================================================================
void cb_call SetParameter
		(
		const Coord_view&	view
		)
{
	DPI		dpi	= view.GetDPI();
	frect	v	= view.GetView();
	OutlineGenStroke_bs<IPen_ipr>::SetStrokeWidth( VtoP_l( dpi , v , m_width ) );
}
// "public" functions
public:
//=================================================================================================
void SetWidth
		(
		const value_ipr&	w
		)
{
	m_width	= w;
}
};
/**************************************************************************************************
"PenDash_ipr" class 
**************************************************************************************************/
class PenDash_ipr : 
	public OutlineGenDash_bs<IPen_ipr> , 
	virtual public object_base
{
// query
	query_begin()
	iface_hook( IOutlineGen , IOutlineGen_IID )
	iface_hook( IPen_ipr , IPen_ipr_IID )
	query_end( object_base )
	
// variable member
private:
	value_ipr			m_width;
	value_ipr			m_offset;
	Array<value_ipr>	m_dash;
	Array<float>		m_dash_f;
	
// "IPaint_ipr" interface functions
public:
//=================================================================================================
void cb_call SetParameter
		(
		const Coord_view&	view
		)
{
	DPI		dpi	= view.GetDPI();
	frect	v	= view.GetView();

	// dash
	int		dashoff , dashnum = m_dash.GetDatanum();
	int		dashnum_f	= dashnum;// + ( (dashnum & 1) == 0 ? 0 : 1 );
	m_dash_f.Resize( dashnum_f );
	for( dashoff = 0 ; dashoff < dashnum ; dashoff++ )
		m_dash_f[ dashoff ]	= VtoP_l( dpi , v , m_dash[ dashoff ] );

	OutlineGenDash_bs<IPen_ipr>::SetDash( m_dash_f.GetConstPtr() , m_dash_f.GetDatanum() , VtoP_l( dpi , v , m_offset ) );
	OutlineGenDash_bs<IPen_ipr>::SetStrokeWidth( VtoP_l( dpi , v , m_width ) );
}
// "public" functions
public:
//=================================================================================================
PenDash_ipr() : m_width( value_ipr::px , 1 )
{
}
//=================================================================================================
void SetWidth
		(
		const value_ipr&	w
		)
{
	m_width	= w;
}
//=================================================================================================
void SetDash
		(
		const value_ipr		dashlist[] , 
		int					dashnum , 
		const value_ipr&	offset
		)
{
	int	dashoff;
	m_dash.Resize( dashnum );
	for( dashoff = 0 ; dashoff < dashnum ; dashoff++ )
		m_dash[ dashoff ] = dashlist[ dashoff ];
	m_offset	= offset;
}
};
/**************************************************************************************************
"ClipRelease_clipcmd" class 
**************************************************************************************************/
class ClipRelease_clipcmd : 
	public IClip_clipcmd , 
	virtual public object_base
{
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	query_end( object_base )

// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		)
{
	attr->ReleaseClip();
}
};
/**************************************************************************************************
"ClipLine_clipcmd" class 
**************************************************************************************************/
class ClipLine_clipcmd : 
	public IClip_clipcmd , 
	virtual public object_base
{
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	query_end( object_base )

public:
	points_ipr				m_points;
	PaintUnit				m_unit;
	faffine					m_transform;
	
private:
	instance<PathLogic>	m_path;
	Array<fvector2>			m_points_vec;
	
// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		)
{
	int		num = m_points.GetPointnum();
	if( num < 2 )
		return;

	// coord
	Coord_view	coord	= attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();

	// to value
	int		off;
	m_points_vec.Resize( num );
	for( off = 0 ; off < num ; off++ )
		m_points_vec[off]	= VtoP( m_unit , dpi , view , boundbox , m_points[ off ] );

	// path
	m_path->Reset();
	m_path->Move( m_points_vec[0] , faffine() , true );
	m_path->Line( num - 1 , &m_points_vec[1] );
	attr->SetClip( (iPathLogicInfo)m_path , m_transform );
}
//=================================================================================================
ClipLine_clipcmd() : m_unit( ViewSpace_PaintUnit )
{
}
};
/**************************************************************************************************
"ClipBezierQ_clipcmd" class 
**************************************************************************************************/
class ClipBezierQ_clipcmd :
	public IClip_clipcmd , 
	virtual public object_base
{
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	query_end( object_base )

public:
	points_ipr				m_points;
	PaintUnit				m_unit;
	faffine					m_transform;

private:
	instance<PathLogic>	m_path;
	Array<fvector2>			m_points_vec;
		
// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		)
{
	int		num = m_points.GetPointnum();
	if( num < 3 )
		return;
	if( ( ( num - 1 ) & 1 ) != 0 )
		return;

	// coord
	Coord_view	coord	= attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();

	// to value
	int		off;
	m_points_vec.Resize( num );
	for( off = 0 ; off < num ; off++ )
		m_points_vec[off]	= VtoP( m_unit , dpi , view , boundbox , m_points[ off ] );

	// path
	m_path->Reset();
	m_path->Move( m_points_vec[0] , faffine() , true );
	m_path->BezierQ( num - 1 , &m_points_vec[1] );
	attr->SetClip( (iPathLogicInfo)m_path , m_transform );
}
public:
//=================================================================================================
ClipBezierQ_clipcmd() : m_unit( ViewSpace_PaintUnit )
{
}
};
/**************************************************************************************************
"ClipBezierC_clipcmd" class 
**************************************************************************************************/
class ClipBezierC_clipcmd : 
	public IClip_clipcmd , 
	virtual public object_base
{
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	query_end( object_base )

public:
	points_ipr				m_points;
	PaintUnit				m_unit;
	faffine					m_transform;

private:
	instance<PathLogic>	m_path;
	Array<fvector2>			m_points_vec;
		
// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		)
{
	int		num = m_points.GetPointnum();
	if( num < 4 )
		return;
	if( ( ( num - 1 ) % 3 ) != 0 )
		return;

	// coord
	Coord_view	coord	= attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();

	// to value
	int		off;
	m_points_vec.Resize( num );
	for( off = 0 ; off < num ; off++ )
		m_points_vec[off]	= VtoP( m_unit , dpi , view , boundbox , m_points[ off ] );

	// path
	m_path->Reset();
	m_path->Move( m_points_vec[0] , faffine() , true );
	m_path->BezierC( num - 1 , &m_points_vec[1] );
	attr->SetClip( (iPathLogicInfo)m_path , m_transform );
}
//=================================================================================================
ClipBezierC_clipcmd() : m_unit( ViewSpace_PaintUnit )
{
}
};
/**************************************************************************************************
"ClipArcAngle_clipcmd" class 
**************************************************************************************************/
class ClipArcAngle_clipcmd :
	public IClip_clipcmd , 
	virtual public object_base
{
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	query_end( object_base )

public:
	point_ipr				m_sp;
	point_ipr				m_cp;
	float					m_ry;
	float					m_angle;
	PaintUnit				m_unit;
	faffine					m_transform;

private:
	instance<PathLogic>	m_path;
		
// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		)
{
	// coord
	Coord_view	coord	= attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();
	
	// to value
	fvector2	sp	= VtoP( m_unit , dpi , view , boundbox , m_sp );
	fvector2	cp	= VtoP( m_unit , dpi , view , boundbox , m_cp );

	// path
	m_path->Reset();
	m_path->Move( sp , faffine() , true );
	m_path->Arc( cp , m_ry , m_angle );
	attr->SetClip( (iPathLogicInfo)m_path , m_transform );
}
//=================================================================================================
ClipArcAngle_clipcmd() :
		m_ry( 1.0f ) , 
		m_angle( PI_2_f ) , 
		m_unit( ViewSpace_PaintUnit )
{
}
};
/**************************************************************************************************
"ClipArcSweep_clipcmd" class 
**************************************************************************************************/
class ClipArcSweep_clipcmd : 
	public IClip_clipcmd , 
	virtual public object_base
{
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	query_end( object_base )

public:
	point_ipr				m_sp;
	point_ipr				m_tp;
	value_ipr				m_rx;
	value_ipr				m_ry;
	float					m_x_axis_rot;
	bool					m_large;
	bool					m_sweep;
	PaintUnit				m_unit;
	faffine					m_transform;

private:
	instance<PathLogic>	m_path;
		
// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox 
		)
{
	// coord
	Coord_view	coord	= attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();
	
	// to value
	fvector2	sp	= VtoP( m_unit , dpi , view , boundbox , m_sp );
	fvector2	tp	= VtoP( m_unit , dpi , view , boundbox , m_tp );
	float		rx	= VtoP_x( m_unit , dpi , view , boundbox , m_rx );
	float		ry	= VtoP_y( m_unit , dpi , view , boundbox , m_ry );

	// path
	m_path->Reset();
	m_path->Move( sp , faffine() , true );
	m_path->Arc( rx , ry , m_x_axis_rot , m_large , m_sweep , tp );
	attr->SetClip( (iPathLogicInfo)m_path , m_transform );
}
//=================================================================================================
ClipArcSweep_clipcmd() :
		m_x_axis_rot( 0.0f ) , 
		m_large( true ) , 
		m_sweep( true ) , 
		m_unit( ViewSpace_PaintUnit )
{
}
};
/**************************************************************************************************
"ClipCircle_clipcmd" class 
**************************************************************************************************/
class ClipCircle_clipcmd : 
	public IClip_clipcmd , 
	virtual public object_base
{
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	query_end( object_base )

public:
	point_ipr				m_cp;
	value_ipr				m_r;
	PaintUnit				m_unit;
	faffine					m_transform;

private:
	instance<PathLogic>	m_path;
		
// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		)
{
	// coord
	Coord_view	coord	= attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();
	
	// to value
	float		r	= VtoP_l( m_unit , dpi , view , boundbox , m_r );
	fvector2	cp	= VtoP( m_unit , dpi , view , boundbox , m_cp );
	fvector2	sp	= fvector2( cp.x - r , cp.y );

	// path
	m_path->Reset();
	m_path->Move( sp , faffine() , true );
	m_path->Arc( cp , 1.0f , PI_2_f );
	attr->SetClip( (iPathLogicInfo)m_path , m_transform );
}
// "IClip_clipcmd" interface functions
public:
//=================================================================================================
ClipCircle_clipcmd() : 
		m_r( value_ipr::px , 1.0f ) , 
		m_unit( ViewSpace_PaintUnit )
{
}
};
/**************************************************************************************************
"ClipEllipse_clipcmd" class 
**************************************************************************************************/
class ClipEllipse_clipcmd : 
	public IClip_clipcmd , 
	virtual public object_base
{
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	query_end( object_base )

public:
	point_ipr				m_cp;
	value_ipr				m_rx;
	value_ipr				m_ry;
	PaintUnit				m_unit;
	faffine					m_transform;

private:
	instance<PathLogic>	m_path;
		
// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		)
{
	// coord
	Coord_view	coord	= attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();
	
	// to value
	float		rx	= VtoP_x( m_unit , dpi , view , boundbox , m_rx );
	float		ry	= VtoP_y( m_unit , dpi , view , boundbox , m_ry );
	fvector2	cp	= VtoP( m_unit , dpi , view , boundbox , m_cp );
	fvector2	sp	= fvector2( cp.x - rx , cp.y );

	// path
	m_path->Reset();
	m_path->Move( sp , faffine() , true );
	m_path->Arc( cp , ry / rx , PI_2_f );
	attr->SetClip( (iPathLogicInfo)m_path , m_transform );
}
// "IClip_clipcmd" interface functions
public:
//=================================================================================================
ClipEllipse_clipcmd() : 
		m_rx( value_ipr::px , 1.0f ) , 
		m_ry( value_ipr::px , 1.0f ) , 
		m_unit( ViewSpace_PaintUnit )
{
}
};
/**************************************************************************************************
"ClipRect_clipcmd" class 
**************************************************************************************************/
class ClipRect_clipcmd : 
	public IClip_clipcmd , 
	virtual public object_base
{
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	query_end( object_base )
public:
	rect_ipr				m_rect;
	value_ipr				m_rx;
	value_ipr				m_ry;
	PaintUnit				m_unit;
	faffine					m_transform;

private:
	instance<PathLogic>	m_path;
		
// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		)
{
	// coord
	Coord_view	coord	= attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();
	
	// to value
	frect		r	= VtoP( m_unit , dpi , view , boundbox , m_rect ).Normalize();
	float		rx	= clip( VtoP_w( dpi , r , m_rx ) , 0.0f , r.Width() / 2.0f );
	float		ry	= clip( VtoP_h( dpi , r , m_ry ) , 0.0f , r.Height() / 2.0f );

	if( rx == 0.0f || ry == 0.0f )
	{
		m_path->Reset();
		m_path->Move( fvector2( r.xmin , r.ymin ) , faffine() , true );
		m_path->Line( 1 , &fvector2( r.xmax , r.ymin ) );
		m_path->Line( 1 , &fvector2( r.xmax , r.ymax ) );
		m_path->Line( 1 , &fvector2( r.xmin , r.ymax ) );
		attr->SetClip( (iPathLogicInfo)m_path , m_transform );
	}
	else
	{
		float		dy = ry / rx;
		m_path->Reset();
		m_path->Move( fvector2( r.xmin + rx , r.ymin ) , faffine() , true );
		m_path->Line( 1 , &fvector2( r.xmax - rx , r.ymin ) );
		m_path->Arc( fvector2( r.xmax - rx , r.ymin + ry ) , dy , PI_R2_f );
		m_path->Line( 1 , &fvector2( r.xmax , r.ymax - ry ) );
		m_path->Arc( fvector2( r.xmax - rx , r.ymax - ry ) , dy , PI_R2_f );
		m_path->Line( 1 , &fvector2( r.xmin + rx , r.ymax ) );
		m_path->Arc( fvector2( r.xmin + rx , r.ymax - ry ) , dy , PI_R2_f );
		m_path->Line( 1 , &fvector2( r.xmin , r.ymin + ry ) );
		m_path->Arc( fvector2( r.xmin + rx , r.ymin + ry ) , dy , PI_R2_f );
		attr->SetClip( (iPathLogicInfo)m_path , m_transform );
	}
}
//=================================================================================================
ClipRect_clipcmd() : 
		m_unit( ViewSpace_PaintUnit )
{
}
};
/**************************************************************************************************
"ClipPath_clipcmd" class 
**************************************************************************************************/
class ClipPath_clipcmd : 
	public IClip_clipcmd , 
	virtual public object_base
{
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	query_end( object_base )

public:
	iPathLogicInfo		m_clip;
	faffine				m_transform;
		
// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		)
{
	attr->SetClip( (iPathLogicInfo)m_clip , m_transform );
}
};
/**************************************************************************************************
"ClipText_clipcmd" class 
**************************************************************************************************/
class ClipText_clipcmd : 
	public IClip_clipcmd , 
	virtual public object_base
{
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	query_end( object_base )

public:
	wstring					m_text;
	iFont					m_font;
	value_ip				m_fontsize;
	point_ipr				m_pos;
	PaintUnit				m_unit;
	faffine					m_transform;
	
private:
	instance<Path>		m_text_path;
	float					m_last_fontsize;
	fvector2				m_last_fontpos;

// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		)
{
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	float		fontsize	= VtoP_y( dpi , m_fontsize );
	fvector2	fontpos		= VtoP( dpi , view , m_pos );
	
	// path
	if( fontsize != m_last_fontsize || m_last_fontpos != fontpos )
	{
		m_font->SetFontSize( fsize( 0.0f ,fontsize ) );
		m_last_fontsize	= fontsize;
		m_last_fontpos	= fontpos;
		CreateTextPath( (iPath)m_text_path , m_text.c_str() , m_text.length() , m_font );
		m_text_path->MulTransform( faffine::GetMove( fontpos ) );
	}
	attr->SetClip( (iPathLogicInfo)m_text_path , m_transform );
}
//=================================================================================================
ClipText_clipcmd() : 
		m_fontsize( value_ip::px , 12.0f ) , 
		m_last_fontsize( -1.0f ) , 
		m_unit( ViewSpace_PaintUnit )
{
}
};
/**************************************************************************************************
"ClipList_clipcmds" class 
**************************************************************************************************/
class ClipList_clipcmds : 
	public IClip_clipcmds , 
	virtual public object_base
{
// query
	query_begin()
	iface_hook( IClip_clipcmd , IClip_clipcmd_IID )
	iface_hook( IClip_clipcmds , IClip_clipcmds_IID )
	query_end( object_base )
	
// member class
private:
	class ClipSeg
	{
	public:
		ClipSeg*		m_next;
		iClip_clipcmd	m_cmd;
		ClipSeg() : m_next( 0 ){}
	};
// variable member
private:
	ClipSeg*				m_first;
	ClipSeg*				m_last;

// "IClip_clipcmd" interface functions
public:
//=================================================================================================
void ExecuteCmd
		(
		IGraphicsAttrCmd*	attr , 
		const frect&		boundbox
		)
{
	if( m_first == 0 )
		return;
	
	ClipSeg*	p = m_first;
	while( p != 0 )
	{
		p->m_cmd->ExecuteCmd( attr , boundbox );
		p = p->m_next;
	}
}
// "IClip_clipcmds" interface functions
public:
//=================================================================================================
void AddCmd
		(
		iClip_clipcmd&		cmd
		)
{
	ClipSeg*	seg = new ClipSeg();
	seg->m_cmd	= cmd;
	( m_last == 0 ? m_first : m_last->m_next ) = seg;
	m_last	= seg;
}
// public functions
public:
//=================================================================================================
ClipList_clipcmds() : m_first(0) , m_last(0)
{
}
//=================================================================================================
~ClipList_clipcmds()
{
	ClipSeg*	p = m_first;
	while( p != 0 )
	{
		ClipSeg*	n = p->m_next;
		delete p;
		p =n;
	}
	m_first	= 0;
	m_last	= 0;
}
};
/**************************************************************************************************
"CmdBase_cmd" class 
**************************************************************************************************/
class CmdBase_cmd : 
	virtual public object_base , 
	public IGraphicsCmd
{
// query
	query_begin();
	iface_hook( IGraphicsCmd , IGraphicsCmd_IID )
	query_end( object_base );
	
// protected functions
protected:
//=================================================================================================
void PaintOutline
		(
		IGraphicsAttrCmd*				attr ,
		iOutline&						outline , 
		iClip_clipcmd&					clip , 
		const Coord_view&				coord ,  
		PathFillRule					fillrule , 
		iPaint_ipr&						paint , 
		iBlender&						blender , 
		float							opacity , 
		iEdgemapOutline&				edgemap , 
		instance<RendererOutline>&	render
		)
{
	OutlineInfo	oi;
	if( false == outline->GetOutlineInfo( &oi ) )
		return;
	if( clip == true )
		clip->ExecuteCmd( attr , oi.m_boundbox );
		
	// edgemap
	faffine			transform	= attr->GetTransform();
	iSurfaceDest	surface		= attr->GetSurface();
	irect			area		= surface->GetDestAvailableArea();
	edgemap->Initialize( attr->GetAntialias() , area );
	edgemap->BeginOutline();
	edgemap->SetOutline( outline , coord.PtoD() * transform );
	edgemap->EndOutline( fillrule );

	// clip
	iEdgemapOutline		clip_edgemap = attr->GetClip();
	if( clip_edgemap == true )
		edgemap->Operate( And_PathOperator , clip_edgemap );

	// paint
	paint->SetParameter( coord , oi.m_boundbox , transform );
	render->SetBlender( blender );
	render->SetPaint( (iPaint)paint );
	render->Render( surface , (iEdgemapOutlineInfo)edgemap , &area , 1 , (uint8)(opacity * 255) );
}
//=================================================================================================
void PaintPath
		(
		IGraphicsAttrCmd*				attr ,
		IPathLogicInfo*					path , 
		iClip_clipcmd&					clip , 
		const Coord_view&				coord ,  
		PathFillRule					fillrule , 
		iPaint_ipr&						paint , 
		iBlender&						blender , 
		float							opacity , 
		PathToEdgemap_bs&				path_to_edgemap , 
		iOutlineGen&					outlinegen , 
		iEdgemapOutline&				edgemap , 
		instance<RendererOutline>&	render , 
		float							samplescale = 1.0f
		)
{
	iSurfaceDest	surface		= attr->GetSurface();
	irect			area		= surface->GetDestAvailableArea();
	faffine&		transform	= attr->GetTransform();

	// edgemap
	frect			boundbox;
	outlinegen->SetSampleScale( samplescale * GetSampleScale( coord.PtoD() ) );
	path_to_edgemap.ToEdgemap
		(
		edgemap , 
		path , 
		transform , 
		outlinegen , 
		fillrule , 
		coord.PtoD() , 
		area , 
		attr->GetAntialias() , 
		&boundbox
		);
	// to clip
	if( clip == true )
		clip->ExecuteCmd( attr , boundbox );
				
	// clip
	iEdgemapOutline	clip_edgemap = attr->GetClip();
	if( clip_edgemap == true )
		edgemap->Operate( And_PathOperator , clip_edgemap );

	// paint
	paint->SetParameter( coord , boundbox , transform );
	render->SetBlender( blender );
	render->SetPaint( (iPaint)paint );
	render->Render( surface , (iEdgemapOutlineInfo)edgemap , &area , 1 , (uint8)(opacity * 255) );
}
//=================================================================================================
frect GetBoundBox
		(
		int				vertnum , 
		const fvector2*	vert
		)
{
	frect	bb( vert[0] , vert[0] );
	int		vertoff;
	for( vertoff = 1 ; vertoff < vertnum ; vertoff++ )
	{
		bb.xmin = min( bb.xmin , vert[vertoff].x );
		bb.ymin = min( bb.ymin , vert[vertoff].y );
		bb.xmax = max( bb.xmax , vert[vertoff].x );
		bb.ymax = max( bb.ymax , vert[vertoff].y );
	}
	return bb;
}
//=================================================================================================
void DrawPolygon
		(
		IGraphicsAttrCmd*				attr ,
		int								vertnum , 
		const fvector2*					vert , 
		const fvector2*					uv , 
		iClip_clipcmd&					clip , 
		const Coord_view&				coord ,  
		iTexture&						texture , 
		iBlender&						blender , 
		float							opacity , 
		instance<EdgemapPolygon>&	edgemap_polygon , 
		instance<RendererPolygon>&	render_polygon
		)
{
	iSurfaceDest	surface		= attr->GetSurface();
	irect			area		= surface->GetDestAvailableArea();
	faffine			transform	= attr->GetTransform();

	// clip
	if( clip == true )
		clip->ExecuteCmd( attr , GetBoundBox( vertnum , vert ) );

	// edgemap
	edgemap_polygon->Initialize( attr->GetAntialias() , area );
	edgemap_polygon->AddPolygon( vertnum , vert , uv , coord.PtoD() * transform );

	// clip
	iEdgemapOutline	clip_edgemap = attr->GetClip();
	if( clip_edgemap == true )
		edgemap_polygon->Operate( And_PolygonOperator , clip_edgemap );

	// render
	render_polygon->SetBlender( blender );
	render_polygon->SetTexture( texture );
	render_polygon->Render( surface , (iEdgemapPolygon)edgemap_polygon , &area , 1 , (uint8)(opacity * 255) );
	render_polygon->ReleaseTexture();
}
// public functions
public:
//=================================================================================================
CmdBase_cmd()
{
}
};
/**************************************************************************************************
"PushAttr_cmd" class 
**************************************************************************************************/
class PushAttr_cmd : public CmdBase_cmd
{
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	attr->PushAttr();
}
};
/**************************************************************************************************
"PopAttr_cmd" class 
**************************************************************************************************/
class PopAttr_cmd : public CmdBase_cmd
{
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	attr->PopAttr();
}
};
/**************************************************************************************************
"Antialias_cmd" class 
**************************************************************************************************/
class Antialias_cmd : public CmdBase_cmd
{
public:
	antialias	m_antialias;
	
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	attr->SetAntialias( m_antialias );
}
// public functions
public:
//=================================================================================================
Antialias_cmd() : m_antialias( x4_antialias )
{
}
};
/**************************************************************************************************
"View_cmd" class 
**************************************************************************************************/
class View_cmd : public CmdBase_cmd
{
public:
	bool		m_x_f;
	value_ipr	m_x;
	bool		m_y_f;
	value_ipr	m_y;
	bool		m_w_f;
	value_ipr	m_w;
	bool		m_h_f;
	value_ipr	m_h;
	
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	Coord_view	coord = attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();
	float		x	= ( m_x_f == true ) ? VtoP_x( dpi , view , m_x ) : view.xmin;
	float		y	= ( m_y_f == true ) ? VtoP_y( dpi , view , m_y ) : view.ymin;
	float		w	= ( m_w_f == true ) ? VtoP_x( dpi , view , m_w ) : view.Width();
	float		h	= ( m_h_f == true ) ? VtoP_y( dpi , view , m_h ) : view.Height();
	attr->SetCoord( faffine::GetMove( fvector2( x , y ) ) , dpi , frect( fsize( w , h ) ) );
}
// public functions
public:
//=================================================================================================
View_cmd() : 
	m_x( value_ipr::px , 0 ) , 
	m_y( value_ipr::px , 0 ) , 
	m_w( value_ipr::px , 100 ) , 
	m_h( value_ipr::px , 100 ) , 
	m_x_f( false ) , 
	m_y_f( false ) , 
	m_w_f( false ) , 
	m_h_f( false )
{
}
};
/**************************************************************************************************
"ViewBox_cmd" class 
**************************************************************************************************/
class ViewBox_cmd : public CmdBase_cmd
{
public:
	Coord_view::AspectRatio	m_ratio;
	Coord_view::Align		m_align_h;
	Coord_view::Align		m_align_v;
	value_ipr				m_x;
	value_ipr				m_y;
	value_ipr				m_w;
	value_ipr				m_h;
	
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	Coord_view	coord	= attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();
	float		x	= VtoP_x( dpi , view , m_x );
	float		y	= VtoP_y( dpi , view , m_y );
	float		w	= VtoP_x( dpi , view , m_w );
	float		h	= VtoP_y( dpi , view , m_h );
	
	Coord_view	t( faffine() , dpi , view );
	t.SetView( m_ratio , m_align_h , m_align_v , dpi , frect( x , y , x + w , x + h ) );
	attr->SetCoord( t.GetVtoD() , t.GetDPI() , t.GetView() );
}
// public functions
public:
//=================================================================================================
ViewBox_cmd() : 
	m_ratio( Coord_view::AspectMin ) , 
	m_align_h( Coord_view::MinAlign ) , 
	m_align_v( Coord_view::MinAlign ) , 
	m_x( value_ipr::px , 0 ) , 
	m_y( value_ipr::px , 0 ) , 
	m_w( value_ipr::px , 100 ) , 
	m_h( value_ipr::px , 100 )
{
}
};
/**************************************************************************************************
"Transform_cmd" class 
**************************************************************************************************/
class Transform_cmd : public CmdBase_cmd
{
public:
	faffine		m_transform;
	
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	attr->SetTransform( m_transform );
}
};
/**************************************************************************************************
"ReleaseClip_cmd" class 
**************************************************************************************************/
class ReleaseClip_cmd : public CmdBase_cmd
{
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	attr->ReleaseClip();
}
};
/**************************************************************************************************
"PaintLine_cmd" class 
**************************************************************************************************/
class PaintLine_cmd : public CmdBase_cmd
{
public:
	points_ipr				m_points;
	iPaint_ipr				m_paint;
	iBlender				m_blender;
	float					m_opacity;
	PathFillRule			m_fillrule;
	iClip_clipcmd			m_clip;
	
private:
	instance<Outline>			m_outline;
	instance<EdgemapOutline>		m_edgemap;
	instance<RendererOutline>	m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	int		num = m_points.GetPointnum();
	if( num < 2 )
		return;

	// coord
	Coord_view	coord	= attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();

	// outline
	m_outline->Reset();	
	OutlineNodePtr*	node = &(m_outline->CreateOutline()->m_node);
	int	off;
	for( off = 0 ; off < num ; off++ )
		node = m_outline->InsertNode( node , VtoP( dpi , view , m_points[ off ] ) );

	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
PaintLine_cmd() : m_opacity( 1.0f ) , m_fillrule( Winding_PathFillRule )
{
}
};
/**************************************************************************************************
"PaintBezierQ_cmd" class 
**************************************************************************************************/
class PaintBezierQ_cmd : public CmdBase_cmd
{
public:
	points_ipr							m_points;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	iClip_clipcmd						m_clip;

private:
	Array<fvector2>						m_points_vec;
	instance<Outline>					m_outline;
	instance<OutlineGenPaint>			m_outlinegen_paint;
	instance<PathSegmentToOutline>		m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>			m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	int		num = m_points.GetPointnum();
	if( num < 3 )
		return;
	if( ( ( num - 1 ) & 1 ) != 0 )
		return;

	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();

	// to value
	int		off;
	m_points_vec.Resize( num );
	for( off = 0 ; off < num ; off++ )
		m_points_vec[off]	= VtoP( dpi , view , m_points[ off ] );

	// to outline	
	m_outlinegen_paint->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_outlinegen_paint );
	m_segment_to_outline->Move( m_points_vec[0] , faffine() , true );
	m_segment_to_outline->BezierQ( num-1 , &m_points_vec[1] );
	m_segment_to_outline->End();
	
	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
PaintBezierQ_cmd() : m_opacity( 1.0f ) , m_fillrule( Winding_PathFillRule )
{
}
};
/**************************************************************************************************
"PaintBezierC_cmd" class 
**************************************************************************************************/
class PaintBezierC_cmd : public CmdBase_cmd
{
public:
	points_ipr							m_points;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	iClip_clipcmd						m_clip;

private:
	Array<fvector2>						m_points_vec;
	instance<Outline>					m_outline;
	instance<OutlineGenPaint>			m_outlinegen_paint;
	instance<PathSegmentToOutline>		m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>			m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	int		num = m_points.GetPointnum();
	if( num < 4 )
		return;
	if( ( ( num - 1 ) % 3 ) != 0 )
		return;

	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// to value
	int		off;
	m_points_vec.Resize( num );
	for( off = 0 ; off < num ; off++ )
		m_points_vec[off]	= VtoP( dpi , view , m_points[ off ] );

	// to outline	
	m_outlinegen_paint->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_outlinegen_paint );
	m_segment_to_outline->Move( m_points_vec[0] , faffine() , true );
	m_segment_to_outline->BezierC( num-1 , &m_points_vec[1] );
	m_segment_to_outline->End();
	
	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
PaintBezierC_cmd() : m_opacity( 1.0f ) , m_fillrule( Winding_PathFillRule )
{
}
};
/**************************************************************************************************
"PaintArcAngle_cmd" class 
**************************************************************************************************/
class PaintArcAngle_cmd : public CmdBase_cmd
{
public:
	point_ipr							m_sp;
	point_ipr							m_cp;
	float								m_ry;
	float								m_angle;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	iClip_clipcmd						m_clip;

private:
	Array<fvector2>						m_points_vec;
	instance<Outline>					m_outline;
	instance<OutlineGenPaint>			m_outlinegen_paint;
	instance<PathSegmentToOutline>		m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>			m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// to value
	fvector2	sp	= VtoP( dpi , view , m_sp );
	fvector2	cp	= VtoP( dpi , view , m_cp );

	// to outline	
	m_outlinegen_paint->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_outlinegen_paint );
	m_segment_to_outline->Move( sp , faffine() , true );
	m_segment_to_outline->Arc( cp , m_ry , m_angle );
	m_segment_to_outline->End();
	
	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
PaintArcAngle_cmd() : 
		m_ry( 1.0f ) , 
		m_angle( PI_2_f ) , 
		m_opacity( 1.0f ) , 
		m_fillrule( Winding_PathFillRule )
{
}
};
/**************************************************************************************************
"PaintArcSweep_cmd" class 
**************************************************************************************************/
class PaintArcSweep_cmd : public CmdBase_cmd
{
public:
	point_ipr							m_sp;
	point_ipr							m_tp;
	value_ipr							m_rx;
	value_ipr							m_ry;
	float								m_x_axis_rot;
	bool								m_large;
	bool								m_sweep;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	iClip_clipcmd						m_clip;

private:
	Array<fvector2>						m_points_vec;
	instance<Outline>					m_outline;
	instance<OutlineGenPaint>			m_outlinegen_paint;
	instance<PathSegmentToOutline>		m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>			m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// to value
	fvector2	sp	= VtoP( dpi , view , m_sp );
	fvector2	tp	= VtoP( dpi , view , m_tp );
	float		rx	= VtoP_x( dpi , view , m_rx );
	float		ry	= VtoP_y( dpi , view , m_ry );

	// to outline	
	m_outlinegen_paint->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_outlinegen_paint );
	m_segment_to_outline->Move( sp , faffine() , true );
	m_segment_to_outline->Arc( rx , ry , m_x_axis_rot , m_large , m_sweep , tp );
	m_segment_to_outline->End();
	
	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
PaintArcSweep_cmd() : 
		m_x_axis_rot( 0.0f ) , 
		m_large( true ) , 
		m_sweep( true ) , 
		m_opacity( 1.0f ) , 
		m_fillrule( Winding_PathFillRule )
{
}
};
/**************************************************************************************************
"PaintCircle_cmd" class 
**************************************************************************************************/
class PaintCircle_cmd : public CmdBase_cmd
{
public:
	point_ipr							m_cp;
	value_ipr							m_r;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	iClip_clipcmd						m_clip;

private:
	Array<fvector2>						m_points_vec;
	instance<Outline>				m_outline;
	instance<OutlineGenPaint>		m_outlinegen_paint;
	instance<PathSegmentToOutline>	m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>		m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// to value
	float		r	= VtoP_l( dpi , view , m_r );
	fvector2	cp	= VtoP( dpi , view , m_cp );
	fvector2	sp	= fvector2( cp.x - r , cp.y );

	// to outline	
	m_outlinegen_paint->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_outlinegen_paint );
	m_segment_to_outline->Move( sp , faffine() , true );
	m_segment_to_outline->Arc( cp , 1.0f , PI_2_f );
	m_segment_to_outline->End();
	
	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
PaintCircle_cmd() : 
		m_r( value_ipr::px , 1.0f ) , 
		m_opacity( 1.0f ) , 
		m_fillrule( Winding_PathFillRule )
{
}
};
/**************************************************************************************************
"PaintEllipse_cmd" class 
**************************************************************************************************/
class PaintEllipse_cmd : public CmdBase_cmd
{
public:
	point_ipr							m_cp;
	value_ipr							m_rx;
	value_ipr							m_ry;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	iClip_clipcmd						m_clip;

private:
	Array<fvector2>						m_points_vec;
	instance<Outline>					m_outline;
	instance<OutlineGenPaint>			m_outlinegen_paint;
	instance<PathSegmentToOutline>		m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>			m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// to value
	float		rx	= VtoP_x( dpi , view , m_rx );
	float		ry	= VtoP_y( dpi , view , m_ry );
	fvector2	cp	= VtoP( dpi , view , m_cp );
	fvector2	sp	= fvector2( cp.x - rx , cp.y );

	// to outline	
	m_outlinegen_paint->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_outlinegen_paint );
	m_segment_to_outline->Move( sp , faffine() , true );
	m_segment_to_outline->Arc( cp , ry / rx , PI_2_f );
	m_segment_to_outline->End();
	
	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip ,
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
PaintEllipse_cmd() : 
		m_rx( value_ipr::px , 1.0f ) , 
		m_ry( value_ipr::px , 1.0f ) , 
		m_opacity( 1.0f ) , 
		m_fillrule( Winding_PathFillRule )
{
}
};
/**************************************************************************************************
"PaintRect_cmd" class 
**************************************************************************************************/
class PaintRect_cmd : public CmdBase_cmd
{
public:
	rect_ipr				m_rect;
	value_ipr				m_rx;
	value_ipr				m_ry;
	iPaint_ipr				m_paint;
	iBlender				m_blender;
	float					m_opacity;
	PathFillRule			m_fillrule;
	iClip_clipcmd			m_clip;

private:
	instance<Outline>				m_outline;
	instance<OutlineGenPaint>		m_outlinegen_paint;
	instance<PathSegmentToOutline>	m_segment_to_outline;
	instance<EdgemapOutline>		m_edgemap;
	instance<RendererOutline>		m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view	coord	= attr->GetCoord();
	DPI			dpi		= coord.GetDPI();
	frect		view	= coord.GetView();

	// outline
	frect		r	= VtoP( dpi , view , m_rect ).Normalize();
	float		rx	= clip( VtoP_w( dpi , r , m_rx ) , 0.0f , r.Width() / 2.0f );
	float		ry	= clip( VtoP_h( dpi , r , m_ry ) , 0.0f , r.Height() / 2.0f );

	// to outline	
	m_outlinegen_paint->SetSampleScale( GetSampleScale( coord.PtoD() * attr->GetTransform() ) );
	m_outline->Reset();
	if( rx == 0.0f || ry == 0.0f )
	{
		m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_outlinegen_paint );
		m_segment_to_outline->Move( fvector2( r.xmin , r.ymin ) , faffine() , true );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmax , r.ymin ) );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmax , r.ymax ) );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmin , r.ymax ) );
		m_segment_to_outline->End();
	}
	else
	{
		float		dy = ry / rx;
		m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_outlinegen_paint );
		m_segment_to_outline->Move( fvector2( r.xmin + rx , r.ymin ) , faffine() , true );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmax - rx , r.ymin ) );
		m_segment_to_outline->Arc( fvector2( r.xmax - rx , r.ymin + ry ) , dy , PI_R2_f );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmax , r.ymax - ry ) );
		m_segment_to_outline->Arc( fvector2( r.xmax - rx , r.ymax - ry ) , dy , PI_R2_f );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmin + rx , r.ymax ) );
		m_segment_to_outline->Arc( fvector2( r.xmin + rx , r.ymax - ry ) , dy , PI_R2_f );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmin , r.ymin + ry ) );
		m_segment_to_outline->Arc( fvector2( r.xmin + rx , r.ymin + ry ) , dy , PI_R2_f );
		m_segment_to_outline->End();
	}
	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
PaintRect_cmd() : m_opacity( 1.0f ) , m_fillrule( Winding_PathFillRule )
{
}
};
/**************************************************************************************************
"PaintPath_cmd" class 
**************************************************************************************************/
class PaintPath_cmd : public CmdBase_cmd
{
public:
	iPathLogic							m_path;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	iClip_clipcmd						m_clip;
	
private:
	instance<OutlineGenPaint>		m_outlinegen_paint;
	PathToEdgemap_bs					m_path_to_edgemap;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>		m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view		coord		= attr->GetCoord();
	
	// paint
	PaintPath
			( 
			attr , 
			m_path , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			m_path_to_edgemap , 
			(iOutlineGen)m_outlinegen_paint , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
PaintPath_cmd() : m_opacity( 1.0f ) , m_fillrule( Winding_PathFillRule )
{
}
};
/**************************************************************************************************
"StrokeLine_cmd" class 
**************************************************************************************************/
class StrokeLine_cmd : public CmdBase_cmd
{
public:
	points_ipr				m_points;
	iPen_ipr				m_pen;
	iPaint_ipr				m_paint;
	iBlender				m_blender;
	float					m_opacity;
	PathFillRule			m_fillrule;
	bool					m_close;
	iClip_clipcmd			m_clip;
	
private:
	Array<fvector2>						m_points_vec;
	instance<Outline>				m_outline;
	instance<PathSegmentToOutline>	m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>		m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	int		num = m_points.GetPointnum();
	if( num < 2 )
		return;

	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// vec
	m_points_vec.Resize( num );
	int	off;
	for( off = 0 ; off < num ; off++ )
		m_points_vec[ off ]	= VtoP( dpi , view , m_points[ off ] );
		
	// pen
	m_pen->SetParameter( coord );
	m_pen->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_pen );
	m_segment_to_outline->Move( m_points_vec[0] , faffine() , m_close );
	m_segment_to_outline->Line( num-1 , &m_points_vec[1] );
	m_segment_to_outline->End();

	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
StrokeLine_cmd() : m_opacity( 1.0f ) , m_fillrule( Winding_PathFillRule ) , m_close( false )
{
}
};
/**************************************************************************************************
"StrokeBezierQ_cmd" class 
**************************************************************************************************/
class StrokeBezierQ_cmd : public CmdBase_cmd
{
public:
	points_ipr				m_points;
	iPen_ipr				m_pen;
	iPaint_ipr				m_paint;
	iBlender				m_blender;
	float					m_opacity;
	PathFillRule			m_fillrule;
	bool					m_close;
	iClip_clipcmd			m_clip;
	
private:
	Array<fvector2>						m_points_vec;
	instance<Outline>				m_outline;
	instance<PathSegmentToOutline>	m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>		m_render;

// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	int		num = m_points.GetPointnum();
	if( num < 3 )
		return;
	if( ( ( num - 1 ) & 1 ) != 0 )
		return;

	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// vec
	m_points_vec.Resize( num );
	int	off;
	for( off = 0 ; off < num ; off++ )
		m_points_vec[ off ]	= VtoP( dpi , view , m_points[ off ] );
		
	// pen
	m_pen->SetParameter( coord );
	m_pen->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_pen );
	m_segment_to_outline->Move( m_points_vec[0] , faffine() , m_close );
	m_segment_to_outline->BezierQ( num-1 , &m_points_vec[1] );
	m_segment_to_outline->End();

	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
StrokeBezierQ_cmd() : m_opacity( 1.0f ) , m_fillrule( Winding_PathFillRule ) , m_close( false )
{
}
};
/**************************************************************************************************
"StrokeBezierC_cmd" class 
**************************************************************************************************/
class StrokeBezierC_cmd : public CmdBase_cmd
{
public:
	points_ipr				m_points;
	iPen_ipr				m_pen;
	iPaint_ipr				m_paint;
	iBlender				m_blender;
	float					m_opacity;
	PathFillRule			m_fillrule;
	bool					m_close;
	iClip_clipcmd			m_clip;
	
private:
	Array<fvector2>						m_points_vec;
	instance<Outline>				m_outline;
	instance<PathSegmentToOutline>	m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>		m_render;

// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	int		num = m_points.GetPointnum();
	if( num < 4 )
		return;
	if( ( ( num - 1 ) % 3 ) != 0 )
		return;

	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// vec
	m_points_vec.Resize( num );
	int	off;
	for( off = 0 ; off < num ; off++ )
		m_points_vec[ off ]	= VtoP( dpi , view , m_points[ off ] );
		
	// pen
	m_pen->SetParameter( coord );
	m_pen->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_pen );
	m_segment_to_outline->Move( m_points_vec[0] , faffine() , m_close );
	m_segment_to_outline->BezierQ( num-1 , &m_points_vec[1] );
	m_segment_to_outline->End();

	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
StrokeBezierC_cmd() : m_opacity( 1.0f ) , m_fillrule( Winding_PathFillRule ) , m_close( false )
{
}
};
/**************************************************************************************************
"StrokeArcAngle_cmd" class 
**************************************************************************************************/
class StrokeArcAngle_cmd : public CmdBase_cmd
{
public:
	point_ipr							m_sp;
	point_ipr							m_cp;
	float								m_ry;
	float								m_angle;
	iPen_ipr							m_pen;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	bool								m_close;
	iClip_clipcmd						m_clip;
	
private:
	instance<Outline>				m_outline;
	instance<PathSegmentToOutline>	m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>		m_render;

// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// to value
	fvector2	sp	= VtoP( dpi , view , m_sp );
	fvector2	cp	= VtoP( dpi , view , m_cp );
		
	// pen
	m_pen->SetParameter( coord );
	m_pen->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_pen );
	m_segment_to_outline->Move( sp , faffine() , m_close );
	m_segment_to_outline->Arc( cp , m_ry , m_angle );
	m_segment_to_outline->End();

	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
StrokeArcAngle_cmd() : 
		m_ry( 1.0f ) , 
		m_angle( PI_2_f ) , 
		m_opacity( 1.0f ) , 
		m_fillrule( Winding_PathFillRule ) , 
		m_close( false )
{
}
};
/**************************************************************************************************
"StrokeArcSweep_cmd" class 
**************************************************************************************************/
class StrokeArcSweep_cmd : public CmdBase_cmd
{
public:
	point_ipr							m_sp;
	point_ipr							m_tp;
	value_ipr							m_rx;
	value_ipr							m_ry;
	float								m_x_axis_rot;
	bool								m_large;
	bool								m_sweep;
	iPen_ipr							m_pen;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	bool								m_close;
	iClip_clipcmd						m_clip;
	
private:
	instance<Outline>				m_outline;
	instance<PathSegmentToOutline>	m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>		m_render;

// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// to value
	fvector2	sp	= VtoP( dpi , view , m_sp );
	fvector2	tp	= VtoP( dpi , view , m_tp );
	float		rx	= VtoP_x( dpi , view , m_rx );
	float		ry	= VtoP_y( dpi , view , m_ry );
		
	// pen
	m_pen->SetParameter( coord );
	m_pen->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_pen );
	m_segment_to_outline->Move( sp , faffine() , m_close );
	m_segment_to_outline->Arc( rx , ry , m_x_axis_rot , m_large , m_sweep , tp );
	m_segment_to_outline->End();

	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
StrokeArcSweep_cmd() : 
		m_x_axis_rot( 0.0f ) , 
		m_large( true ) , 
		m_sweep( true ) , 
		m_opacity( 1.0f ) , 
		m_fillrule( Winding_PathFillRule ) , 
		m_close( false )
{
}
};
/**************************************************************************************************
"StrokeCircle_cmd" class 
**************************************************************************************************/
class StrokeCircle_cmd : public CmdBase_cmd
{
public:
	point_ipr							m_cp;
	value_ipr							m_r;
	iPen_ipr							m_pen;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	bool								m_close;
	iClip_clipcmd						m_clip;
	
private:
	instance<Outline>				m_outline;
	instance<PathSegmentToOutline>	m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>		m_render;

// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// to value
	float		r	= VtoP_l( dpi , view , m_r );
	fvector2	cp	= VtoP( dpi , view , m_cp );
	fvector2	sp	= fvector2( cp.x - r , cp.y );

	// pen
	m_pen->SetParameter( coord );
	m_pen->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_pen );
	m_segment_to_outline->Move( sp , faffine() , m_close );
	m_segment_to_outline->Arc( cp , 1.0f , PI_2_f );
	m_segment_to_outline->End();

	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
StrokeCircle_cmd() : 
		m_r( value_ipr::px , 1.0f ) , 
		m_opacity( 1.0f ) , 
		m_fillrule( Winding_PathFillRule ) , 
		m_close( false )
{
}
};
/**************************************************************************************************
"StrokeEllipse_cmd" class 
**************************************************************************************************/
class StrokeEllipse_cmd : public CmdBase_cmd
{
public:
	point_ipr							m_cp;
	value_ipr							m_rx;
	value_ipr							m_ry;
	iPen_ipr							m_pen;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	bool								m_close;
	iClip_clipcmd						m_clip;
	
private:
	instance<Outline>				m_outline;
	instance<PathSegmentToOutline>	m_segment_to_outline;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>		m_render;

// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	faffine		transform	= attr->GetTransform();
	
	// to value
	float		rx	= VtoP_x( dpi , view , m_rx );
	float		ry	= VtoP_y( dpi , view , m_ry );
	fvector2	cp	= VtoP( dpi , view , m_cp );
	fvector2	sp	= fvector2( cp.x - rx , cp.y );

	// pen
	m_pen->SetParameter( coord );
	m_pen->SetSampleScale( GetSampleScale( coord.PtoD() * transform ) );
	m_outline->Reset();
	m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_pen );
	m_segment_to_outline->Move( sp , faffine() , m_close );
	m_segment_to_outline->Arc( cp , ry / rx , PI_2_f );
	m_segment_to_outline->End();

	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
StrokeEllipse_cmd() : 
		m_rx( value_ipr::px , 1.0f ) , 
		m_ry( value_ipr::px , 1.0f ) , 
		m_opacity( 1.0f ) , 
		m_fillrule( Winding_PathFillRule ) , 
		m_close( false )
{
}
};
/**************************************************************************************************
"StrokeRect_cmd" class 
**************************************************************************************************/
class StrokeRect_cmd : public CmdBase_cmd
{
public:
	rect_ipr						m_rect;
	value_ipr						m_rx;
	value_ipr						m_ry;
	iPen_ipr						m_pen;
	iPaint_ipr						m_paint;
	iBlender						m_blender;
	float							m_opacity;
	PathFillRule					m_fillrule;
	bool							m_close;
	iClip_clipcmd					m_clip;
	
private:
	instance<Outline>				m_outline;
	instance<PathSegmentToOutline>	m_segment_to_outline;
	instance<EdgemapOutline>		m_edgemap;
	instance<RendererOutline>		m_render;

// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	
	// outline
	frect		r	= VtoP( dpi , view , m_rect ).Normalize();
	float		rx	= clip( VtoP_w( dpi , r , m_rx ) , 0.0f , r.Width() / 2.0f );
	float		ry	= clip( VtoP_h( dpi , r , m_ry ) , 0.0f , r.Height() / 2.0f );

	// to outline	
	m_pen->SetParameter( coord );
	m_pen->SetSampleScale( GetSampleScale( coord.PtoD() * attr->GetTransform() ) );
	m_outline->Reset();
	if( rx == 0.0f || ry == 0.0f )
	{
		m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_pen );
		m_segment_to_outline->Move( fvector2( r.xmin , r.ymin ) , faffine() , true );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmax , r.ymin ) );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmax , r.ymax ) );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmin , r.ymax ) );
		m_segment_to_outline->End();
	}
	else
	{
		float		dy = ry / rx;
		m_segment_to_outline->Begin( (iOutline)m_outline , (iOutlineGen)m_pen );
		m_segment_to_outline->Move( fvector2( r.xmin + rx , r.ymin ) , faffine() , true );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmax - rx , r.ymin ) );
		m_segment_to_outline->Arc( fvector2( r.xmax - rx , r.ymin + ry ) , dy , PI_R2_f );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmax , r.ymax - ry ) );
		m_segment_to_outline->Arc( fvector2( r.xmax - rx , r.ymax - ry ) , dy , PI_R2_f );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmin + rx , r.ymax ) );
		m_segment_to_outline->Arc( fvector2( r.xmin + rx , r.ymax - ry ) , dy , PI_R2_f );
		m_segment_to_outline->Line( 1 , &fvector2( r.xmin , r.ymin + ry ) );
		m_segment_to_outline->Arc( fvector2( r.xmin + rx , r.ymin + ry ) , dy , PI_R2_f );
		m_segment_to_outline->End();
	}

	// render
	PaintOutline
			( 
			attr , 
			(iOutline)m_outline , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
StrokeRect_cmd() : 
		m_opacity( 1.0f ) , 
		m_fillrule( Winding_PathFillRule ) , 
		m_close( false )
{
}
};
/**************************************************************************************************
"StrokePath_cmd" class 
**************************************************************************************************/
class StrokePath_cmd : public CmdBase_cmd
{
public:
	iPathLogic							m_path;
	iPen_ipr							m_pen;
	iPaint_ipr							m_paint;
	iBlender							m_blender;
	float								m_opacity;
	PathFillRule						m_fillrule;
	iClip_clipcmd						m_clip;

private:
	PathToEdgemap_bs					m_path_to_edgemap;
	instance<EdgemapOutline>			m_edgemap;
	instance<RendererOutline>		m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	if( m_paint == false )
		return;
	// coord
	Coord_view		coord		= attr->GetCoord();
	DPI				dpi			= coord.GetDPI();
	frect			view		= coord.GetView();
	
	// paint
	m_pen->SetParameter( coord );
	PaintPath
			( 
			attr , 
			m_path , 
			m_clip , 
			coord , 
			m_fillrule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			m_path_to_edgemap , 
			(iOutlineGen)m_pen , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
StrokePath_cmd() : m_opacity( 1.0f ) , m_fillrule( Winding_PathFillRule )
{
}
};
/**************************************************************************************************
"DrawPolygon_cmd" class 
**************************************************************************************************/
class DrawPolygon_cmd : public CmdBase_cmd
{
public:
	points_ipr							m_points;
	Array<fvector2>						m_uv;
	iTexture							m_texture;
	iBlender							m_blender;
	float								m_opacity;
	iClip_clipcmd						m_clip;

private:
	Array<fvector2>						m_points_vec;
	instance<EdgemapPolygon>			m_edgemap_polygon;
	instance<RendererPolygon>		m_render_polygon;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	int		vertnum = m_points.GetPointnum();
	if( vertnum < 3 )
		return;
	if( m_uv.GetDatanum() != vertnum )
		return;
			
	// coord
	Coord_view		coord		= attr->GetCoord();
	DPI				dpi			= coord.GetDPI();
	frect			view		= coord.GetView();

	// vec
	m_points_vec.Resize( vertnum );
	int	off;
	for( off = 0 ; off < vertnum ; off++ )
		m_points_vec[ off ]	= VtoP( dpi , view , m_points[ off ] );

	// draw
	DrawPolygon
			( 
			attr , 
			vertnum , 
			m_points_vec.GetConstPtr() , 
			m_uv.GetConstPtr() , 
			m_clip , 
			coord , 
			m_texture , 
			m_blender , 
			m_opacity , 
			m_edgemap_polygon , 
			m_render_polygon 
			);
}
// public functions
public:
//=================================================================================================
DrawPolygon_cmd() : m_opacity( 1.0f )
{
}
};
/**************************************************************************************************
"BitBlt_cmd" class 
**************************************************************************************************/
class BitBlt_cmd : public CmdBase_cmd
{
public:
	point_ipr							m_dest_pos;
	point_ipr							m_src_pos;
	iTexture							m_texture;
	iBlender							m_blender;
	float								m_opacity;
	iClip_clipcmd						m_clip;

private:
	instance<EdgemapPolygon>			m_edgemap_polygon;
	instance<RendererPolygon>		m_render_polygon;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	// coord
	Coord_view		coord		= attr->GetCoord();
	DPI				dpi			= coord.GetDPI();
	frect			view		= coord.GetView();

	// vertex
	fsize		ss		= m_texture->TextureSize();
	fsize		ts		= ss;
	fvector2	sp		= VtoP( m_texture->TextureDPI() , ss , m_src_pos );
	frect		tr		= frect( ts ).Move( -sp ).Move( VtoP( dpi , view , m_dest_pos ) );
	fvector2	vert[4]	= 
		{
		fvector2( tr.xmin , tr.ymin ) , 
		fvector2( tr.xmax , tr.ymin ) , 
		fvector2( tr.xmax , tr.ymax ) , 
		fvector2( tr.xmin , tr.ymax )
		};
	fvector2	uv[4]	= 
		{
		fvector2( 0.0f , 0.0f ) , 
		fvector2( 1.0f , 0.0f ) , 
		fvector2( 1.0f , 1.0f ) , 
		fvector2( 0.0f , 1.0f )
		};

	// draw
	DrawPolygon
			( 
			attr , 
			_countof( vert ) , 
			vert , 
			uv ,
			m_clip ,  
			coord , 
			m_texture , 
			m_blender , 
			m_opacity , 
			m_edgemap_polygon , 
			m_render_polygon 
			);
}
// public functions
public:
//=================================================================================================
BitBlt_cmd() : m_opacity( 1.0f )
{
}
};
/**************************************************************************************************
"StretchBlt_cmd" class 
**************************************************************************************************/
class StretchBlt_cmd : public CmdBase_cmd
{
public:
	rect_ipr							m_dest_rect;
	rect_ipr							m_src_rect;
	iTexture							m_texture;
	iBlender							m_blender;
	float								m_opacity;
	iClip_clipcmd						m_clip;

private:
	instance<EdgemapPolygon>			m_edgemap_polygon;
	instance<RendererPolygon>		m_render_polygon;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	// coord
	Coord_view		coord		= attr->GetCoord();
	DPI				dpi			= coord.GetDPI();
	frect			view		= coord.GetView();

	// vertex
	DPI		sdpi		= m_texture->TextureDPI();
	frect	sview		= m_texture->TextureSize();
	frect	dest_rect	= VtoP( dpi , view , m_dest_rect );
	frect	src_rect	= VtoP( dpi , sview , m_src_rect );
	src_rect.xmin /= sview.Width();
	src_rect.ymin /= sview.Height();
	src_rect.xmax /= sview.Width();
	src_rect.ymax /= sview.Height();
	fvector2	vert[4]	= 
		{
		fvector2( dest_rect.xmin , dest_rect.ymin ) , 
		fvector2( dest_rect.xmax , dest_rect.ymin ) , 
		fvector2( dest_rect.xmax , dest_rect.ymax ) , 
		fvector2( dest_rect.xmin , dest_rect.ymax )
		};
	fvector2	uv[4]	= 
		{
		fvector2( src_rect.xmin , src_rect.ymin ) , 
		fvector2( src_rect.xmax , src_rect.ymin ) , 
		fvector2( src_rect.xmax , src_rect.ymax ) , 
		fvector2( src_rect.xmin , src_rect.ymax )
		};

	// draw
	DrawPolygon
			( 
			attr , 
			_countof( vert ) , 
			vert , 
			uv , 
			m_clip , 
			coord , 
			m_texture , 
			m_blender , 
			m_opacity , 
			m_edgemap_polygon , 
			m_render_polygon 
			);
}
// public functions
public:
//=================================================================================================
StretchBlt_cmd() : m_opacity( 1.0f )
{
}
};
/**************************************************************************************************
"PaintText_cmd" class 
**************************************************************************************************/
class PaintText_cmd : public CmdBase_cmd
{
public:
	iPaint_ipr						m_paint;
	iBlender						m_blender;
	float							m_opacity;
	iClip_clipcmd					m_clip;

	wstring							m_text;
	iFont							m_font;
	value_ip						m_fontsize;
	point_ipr						m_pos;
	
private:
	instance<Path>					m_text_path;
	float							m_last_fontsize;
	fvector2						m_last_fontpos;
	
	instance<OutlineGenPaint>		m_outlinegen_paint;
	PathToEdgemap_bs				m_path_to_edgemap;
	instance<EdgemapOutline>		m_edgemap;
	instance<RendererOutline>		m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	float		fontsize	= VtoP_y( dpi , m_fontsize );
	fvector2	fontpos		= VtoP( dpi , view , m_pos );
	
	// path
	if( fontsize != m_last_fontsize || fontpos != m_last_fontpos )
	{
		m_font->SetFontSize( fsize( 0.0f ,fontsize ) );
		m_last_fontsize	= fontsize;
		m_last_fontpos	= fontpos;
		CreateTextPath( (iPath)m_text_path , m_text.c_str() , m_text.length() , m_font );
		m_text_path->MulTransform( faffine::GetMove( fontpos ) );
	}

	// paint
	PaintPath
			( 
			attr , 
			(iPath)m_text_path , 
			m_clip , 
			coord , 
			Winding_PathFillRule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			m_path_to_edgemap , 
			(iOutlineGen)m_outlinegen_paint , 
			(iEdgemapOutline)m_edgemap , 
			m_render ,
			3.0f
			);
}
// public functions
public:
//=================================================================================================
PaintText_cmd() : 
		m_opacity( 1.0f ) , 
		m_fontsize( value_ip::px , 12.0f ) , 
		m_last_fontsize( -1.0f )
{
}
};
/**************************************************************************************************
"StrokeText_cmd" class 
**************************************************************************************************/
class StrokeText_cmd : public CmdBase_cmd
{
public:
	iPen_ipr						m_pen;
	iPaint_ipr						m_paint;
	iBlender						m_blender;
	float							m_opacity;
	iClip_clipcmd					m_clip;

	wstring							m_text;
	iFont							m_font;
	value_ip						m_fontsize;
	point_ipr						m_pos;
	
private:
	instance<Path>				m_text_path;
	float							m_last_fontsize;
	fvector2						m_last_fontpos;
	
	PathToEdgemap_bs				m_path_to_edgemap;
	instance<EdgemapOutline>		m_edgemap;
	instance<RendererOutline>	m_render;
		
// "IGraphicsCmd" interface functions
private:
//=================================================================================================
void cb_call ExecuteCmd
		(
		IGraphicsAttrCmd*	attr
		)
{
	// coord
	Coord_view	coord		= attr->GetCoord();
	DPI			dpi			= coord.GetDPI();
	frect		view		= coord.GetView();
	float		fontsize	= VtoP_y( dpi , m_fontsize );
	fvector2	fontpos		= VtoP( dpi , view , m_pos );
	
	// path
	if( fontsize != m_last_fontsize || fontpos != m_last_fontpos )
	{
		m_font->SetFontSize( fsize( 0.0f ,fontsize ) );
		m_last_fontsize	= fontsize;
		m_last_fontpos	= fontpos;
		CreateTextPath( (iPath)m_text_path , m_text.c_str() , m_text.length() , m_font );
		m_text_path->MulTransform( faffine::GetMove( fontpos ) );
	}

	// paint
	m_pen->SetParameter( coord );
	PaintPath
			( 
			attr , 
			(iPath)m_text_path , 
			m_clip , 
			coord , 
			Winding_PathFillRule , 
			m_paint , 
			m_blender , 
			m_opacity , 
			m_path_to_edgemap , 
			(iOutlineGen)m_pen , 
			(iEdgemapOutline)m_edgemap , 
			m_render 
			);
}
// public functions
public:
//=================================================================================================
StrokeText_cmd() : 
		m_opacity( 1.0f ) , 
		m_fontsize( value_ip::px , 12.0f ) , 
		m_last_fontsize( -1.0f )
{
}
};

///////////////////////////////////////////////////////////////////////////////////////////////////
// global variable define

///////////////////////////////////////////////////////////////////////////////////////////////////
// global functions define

};	//namespace

//using namespace icubic;		

#pragma pack( pop )			//release align
