void VRegion::Inset (GReal inHoriz, GReal inVert)
{
	if (fRegion == NULL)
		SetEmpty();
		
#if !USE_GDIPLUS

	GReal	dstRight = fBounds.GetRight() + inHoriz;
	GReal	dstLeft = fBounds.GetLeft() + inHoriz;
	GReal	dstTop = fBounds.GetTop() + inVert;
	GReal	dstBottom = fBounds.GetBottom() + inVert;
	
#if DEBUG_GDI_LIMITS
	assert(Abs(dstRight) <= kMAX_GDI_RGN_COORD);
	assert(Abs(dstLeft) <= kMIN_GDI_RGN_COORD);
	assert(Abs(dstTop) <= kMIN_GDI_RGN_COORD);
	assert(Abs(dstBottom) <= kMAX_GDI_RGN_COORD);
#endif
	
	// Make sure the region isn't too big for Win32
	if (dstRight > kMAX_GDI_RGN_COORD || dstLeft < kMIN_GDI_RGN_COORD
		|| dstBottom > kMAX_GDI_RGN_COORD || dstTop < kMIN_GDI_RGN_COORD) return;
		
	sLONG	rgnSize = ::GetRegionData(fRegion, sizeof(RGNDATA), 0);
	VHandle	vHandle = VMemory::NewHandle(rgnSize);
	VPtr	vPtr = VMemory::LockHandle(vHandle);
		
	// Create a translate matrix
	rgnSize = ::GetRegionData(fRegion, rgnSize, (RGNDATA*)vPtr);
	
	XFORM xForm;
	xForm.eM11 = inHoriz; 
    xForm.eM12 = 0.0;   
    xForm.eM21 = 0.0;   
    xForm.eM22 = inVert;
    xForm.eDx = 0.0;  
    xForm.eDy = 0.0;
    
	HRGN	tempRgn = ::ExtCreateRegion(&xForm, rgnSize, (RGNDATA*)vPtr);
	if (tempRgn != NULL)
	{
		_Release();
		fRegion = tempRgn;
	}
	
	VMemory::DisposeHandle(vHandle);
	
	_AdjustOrigin();
#else
	Gdiplus::Matrix mat;
	
	mat.Translate(inHoriz,inVert);
	mat.Scale((fBounds.GetWidth()-inHoriz)/(GReal)fBounds.GetWidth(),(fBounds.GetHeight()-inVert)/(GReal)fBounds.GetHeight());
	
	fRegion->Transform(&mat);
#endif

	_ComputeBounds();
}
void VGraphicPath::SetSizeBy(GReal inWidth, GReal inHeight)
{
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	if (!VWinD2DGraphicContext::IsAvailable())
	{
#endif
		Gdiplus::Matrix matrix;
		matrix.Scale(1.0 + inWidth / fBounds.GetWidth(), 1.0 + inHeight / fBounds.GetHeight());
		fPath->Transform(&matrix);
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	}
#endif

#if ENABLE_D2D
	if (VWinD2DGraphicContext::IsAvailable() && fPathD2D)
	{
		End();
		
		VAffineTransform mat;
		mat.SetScaling( 1.0 + inWidth / fBounds.GetWidth(), 1.0 + inHeight / fBounds.GetHeight());
		D2D1_MATRIX_3X2_F matNative;
		mat.ToNativeMatrix((D2D_MATRIX_REF)&matNative);

		ID2D1Geometry *sourcePath = fPathD2D;
		
		ID2D1TransformedGeometry *thisPath = NULL;
		VWinD2DGraphicContext::GetMutexFactory().Lock();
		bool ok = SUCCEEDED(VWinD2DGraphicContext::GetFactory()->CreateTransformedGeometry( sourcePath, &matNative, &thisPath));
		VWinD2DGraphicContext::GetMutexFactory().Unlock();
		xbox_assert(ok);
		if (ok)
		{
			fPathD2D = thisPath;
			sourcePath->Release();
		}
		else 
			return;
	}
#endif

	fPolygon.SetSizeBy(inWidth, inHeight);

	if (fComputeBoundsAccurate)
	{
		VPoint inflate( (SmallReal)inWidth, (SmallReal)inHeight);

		if (fPathMax != GP_BOUNDS_MAX_DEFAULT)
			fPathMax += inflate;
	}
	_ComputeBounds();

	if (fCreateStorageForCrispEdges)
	{
		fDrawCmds.push_back( VGraphicPathDrawCmd( GPDCT_SET_SIZE_BY, inWidth, inHeight));
		fCurTransform.Scale( 1 + inWidth / fBounds.GetWidth(), 1 + inHeight / fBounds.GetHeight(), VAffineTransform::MatrixOrderAppend);
	}
}
void VRegion::SetSizeBy (GReal inHoriz, GReal inVert)
{
	if (fRegion == NULL)
		SetEmpty();
		
#if USE_GDIPLUS
	Gdiplus::Matrix mat;
	mat.Scale((fBounds.GetWidth()+inHoriz)/(GReal)fBounds.GetWidth(),(fBounds.GetHeight()+inVert)/(GReal)fBounds.GetHeight());
	fRegion->Transform(&mat);
#else

	GReal	dstWidth = fBounds.GetWidth() + inHoriz;
	GReal	dstHeight = fBounds.GetHeight() + inVert;
	
#if DEBUG_GDI_LIMITS
	assert(dstWidth <= kMAX_GDI_RGN_COORD);
	assert(dstHeight <= kMAX_GDI_RGN_COORD);
#endif
	
	// Make sure the region isn't too big for Win32
	if (dstWidth > kMAX_GDI_RGN_COORD || dstHeight > kMAX_GDI_RGN_COORD) return;
		
	sLONG	rgnSize = ::GetRegionData(fRegion, sizeof(RGNDATA), 0);
	VHandle	vHandle = VMemory::NewHandle(rgnSize);
	VPtr	vPtr = VMemory::LockHandle(vHandle);
		
	rgnSize = ::GetRegionData(fRegion, rgnSize, (RGNDATA*)vPtr);
	
	// Create a scale matrix
	XFORM	xForm;
	xForm.eM11 = dstWidth / fBounds.GetWidth(); 
    xForm.eM12 = 0.0;   
    xForm.eM21 = 0.0;   
    xForm.eM22 = dstHeight / fBounds.GetHeight();
    xForm.eDx = 0.0;  
    xForm.eDy = 0.0;

	HRGN	tempRgn = ::ExtCreateRegion(&xForm, rgnSize, (RGNDATA*)vPtr);
	if (tempRgn != NULL)
	{
		_Release();
		fRegion = tempRgn;
		
		// Region scaling move origin, so reset it
		RECT	rgnRect = { 0, 0, 0, 0 };
		::GetRgnBox(fRegion, &rgnRect);
		::OffsetRgn(fRegion, -rgnRect.left, -rgnRect.top);
		fOffset.SetPosBy( rgnRect.left, rgnRect.top);
	}
	
	VMemory::DisposeHandle(vHandle);
	
#endif

	_ComputeBounds();
}
HRESULT ParaEngine::CCCSFaceLoader::ComposeWithGDIPlus()
{
	HRESULT hr = S_OK;
#ifdef USE_DIRECTX_RENDERER
	// DO the texture composition here
	CGDIEngine* pEngine = CAsyncLoader::GetSingleton().GetGDIEngine();
	if (pEngine == NULL)
		return E_FAIL;
	pEngine->SetRenderTarget(pEngine->CreateGetRenderTargetBySize(CCharCustomizeSysSetting::FaceTexSize));
	pEngine->Begin();

	for (int i = 0; i<CFS_TOTAL_NUM; ++i)
	{
		const CharRegionCoords &coords = CCharCustomizeSysSetting::regions[CR_FACE_BASE + i];
		const FaceTextureComponent& component = m_layers[i];

		// load the component texture
		if (component.name.empty())
			continue;
		string componentfilename = component.name;

		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(componentfilename);
		if (pEntry)
			componentfilename = pEntry->GetLocalFileName();

		// compute the transform matrix
		Gdiplus::Matrix transformMatrix;
		// scale around the center
		float fScale = component.GetScaling();
		if (fabs(fScale)>0.01f)
		{
			transformMatrix.Scale(fScale + 1.f, fScale + 1.f);
		}

		// rotate around the center
		float fRotation = component.GetRotation();
		if (fabs(fRotation) > 0.01f)
		{
			transformMatrix.Rotate(fRotation);
		}

		// translation
		int x, y;
		component.GetPosition(&x, &y);
		transformMatrix.Translate(coords.xpos + (float)x, coords.ypos + (float)y);
		pEngine->SetTransform(&transformMatrix);

		Color color = component.GetColor();
		pEngine->DrawImage(pEngine->LoadTexture(componentfilename, component.name), (float)(-coords.xsize / 2), (float)(-coords.ysize / 2), (float)coords.xsize, (float)coords.ysize, color);

		// for eye and eye bow, there should be a mirrored image, around the center of the render target
		if (i == CFS_EYE || i == CFS_EYEBROW)
		{
			Gdiplus::Matrix reflectMat(-1.f, 0.f, 0.f, 1.f, CCharCustomizeSysSetting::FaceTexSize - (coords.xpos + (float)x) * 2, 0.f);
			transformMatrix.Multiply(&reflectMat);
			pEngine->SetTransform(&transformMatrix);
			pEngine->DrawImage(pEngine->LoadTexture(componentfilename, component.name), (float)(-coords.xsize / 2), (float)(-coords.ysize / 2), (float)coords.xsize, (float)coords.ysize);
		}
	}
	CParaFile::CreateDirectory(m_sFileName.c_str());
	hr = (pEngine->SaveRenderTarget(m_sFileName, CCharCustomizeSysSetting::FaceTexSize, CCharCustomizeSysSetting::FaceTexSize, false, 0)) ? S_OK : E_FAIL;
	pEngine->End();
#endif
	return hr;
}