Exemple #1
0
 ~D2DPathRendererState() {
     if (path)
     {
         path->Release();
         path = NULL;
     }
 }
void VGraphicPath::Widen(const GReal inStrokeWidth, ID2D1StrokeStyle* inStrokeStyle)
{
	xbox_assert(inStrokeStyle);
	End();

	if (fPathD2D != NULL)
	{
		CComPtr<ID2D1StrokeStyle> strokeStyle = (ID2D1StrokeStyle *)inStrokeStyle;
		ID2D1Geometry *oldPath = fPathD2D;

		//create new path
		ID2D1PathGeometry *newPath = NULL;
		VWinD2DGraphicContext::GetMutexFactory().Lock();
		HRESULT hr = VWinD2DGraphicContext::GetFactory()->CreatePathGeometry( &newPath);
		xbox_assert(SUCCEEDED(hr));
		VWinD2DGraphicContext::GetMutexFactory().Unlock();

		//widen current path
		CComPtr<ID2D1GeometrySink> thisGeomSink;
		if (SUCCEEDED(newPath->Open(&thisGeomSink)))
		{
			thisGeomSink->SetFillMode( fFillMode == FILLRULE_EVENODD ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING);

			if (!SUCCEEDED(oldPath->Widen(
							inStrokeWidth,
							strokeStyle,
							NULL,
							0.0f,
							thisGeomSink)))
			{
				newPath->Release();
				return;
			}
			thisGeomSink->Close();
		}

		fPathD2D = newPath;
		oldPath->Release();

		fCreateStorageForCrispEdges = false;
		fHasBezier = false;
		fDrawCmds.clear();
		fCurTransform.MakeIdentity();
	}
}
void VGraphicPath::Begin()
{
#if ENABLE_D2D
	//start to populate geometry
	if (fGeomSink)
		return;
	if (fPathD2D == NULL)
		return;

	ID2D1PathGeometry *thisPath = NULL;
	if (FAILED(fPathD2D->QueryInterface( __uuidof(ID2D1PathGeometry), (void **)&thisPath)))
		return; //no more a ID2D1PathGeometry so skip
	ID2D1GeometrySink *thisGeomSink;
	if (SUCCEEDED(thisPath->Open(&thisGeomSink)))
	{
		fGeomSink = thisGeomSink;
		thisGeomSink->SetFillMode( fFillMode == FILLRULE_EVENODD ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING);
		fFigureIsClosed = true;
	}
	thisPath->Release();
#endif
}
/** combine current path with the specified path
@remarks
	does not update internal polygon
	used only by D2D impl for path clipping implementation
*/
void VGraphicPath::_Combine( const VGraphicPath& inPath, bool inIntersect)
{
	End();

	//ensure proper combination if current path or input path is empty
	if (inPath.GetBounds().GetWidth() == 0.0f || inPath.GetBounds().GetHeight() == 0.0f)
	{
		//input path is empty
		if (inIntersect)
			Clear();
		return;
	}
	if (GetBounds().GetWidth() == 0.0f || GetBounds().GetHeight() == 0.0f)
	{
		//current path is empty
		if (inIntersect)
			return;
		else
			*this = inPath;
		return;
	}

	//combine D2D path if appropriate
	//TODO: make it work for Gdiplus::GraphicPath too ?
	if (fPathD2D != NULL && inPath.GetImplPathD2D())
	{
		ID2D1Geometry *oldPath = fPathD2D;

		//create new path
		ID2D1PathGeometry *newPath = NULL;
		VWinD2DGraphicContext::GetMutexFactory().Lock();
		HRESULT hr = VWinD2DGraphicContext::GetFactory()->CreatePathGeometry( &newPath);
		xbox_assert(SUCCEEDED(hr));
		VWinD2DGraphicContext::GetMutexFactory().Unlock();

		//combine current path with input path
		CComPtr<ID2D1GeometrySink> thisGeomSink;
		if (SUCCEEDED(newPath->Open(&thisGeomSink)))
		{
			thisGeomSink->SetFillMode( fFillMode == FILLRULE_EVENODD ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING);

			if (!SUCCEEDED(oldPath->CombineWithGeometry(
							inPath.GetImplPathD2D(),
							inIntersect ? D2D1_COMBINE_MODE_INTERSECT : D2D1_COMBINE_MODE_UNION,
							NULL,
							0.0f,
							thisGeomSink
							)))
			{
				newPath->Release();
				return;
			}
			thisGeomSink->Close();
		}

		fPathD2D = newPath;
		oldPath->Release();

		if (inIntersect)
			fBounds.Intersect( inPath.GetBounds());
		else
			fBounds.Union( inPath.GetBounds());

		fCreateStorageForCrispEdges = false;
		fHasBezier = false;
		fDrawCmds.clear();
		fCurTransform.MakeIdentity();
	}
}