Beispiel #1
0
//-----------------------------------------------------------------------------
void D2DDrawContext::fillRadialGradient (CGraphicsPath* _path, const CGradient& gradient, const CPoint& center, CCoord radius, const CPoint& originOffset, bool evenOdd, CGraphicsTransform* t)
{
	if (renderTarget == 0)
		return;

	D2DApplyClip ac (this);
	if (ac.isEmpty ())
		return;
	
	D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path);
	if (d2dPath == 0)
		return;

	ID2D1Geometry* path = d2dPath->createPath (evenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING);
	if (path)
	{
		ID2D1Geometry* geometry = 0;
		if (t)
		{
			ID2D1TransformedGeometry* tg = 0;
			getD2DFactory ()->CreateTransformedGeometry (path, convert (*t), &tg);
			geometry = tg;
		}
		else
		{
			geometry = path;
			geometry->AddRef ();
		}
		ID2D1GradientStopCollection* collection = createGradientStopCollection (gradient);
		if (collection)
		{
			// brush properties
			ID2D1RadialGradientBrush* brush = 0;
			D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES properties;
			properties.center = makeD2DPoint (center);
			properties.gradientOriginOffset = makeD2DPoint (originOffset);
			properties.radiusX = (FLOAT)radius;
			properties.radiusY = (FLOAT)radius;

			if (SUCCEEDED (getRenderTarget ()->CreateRadialGradientBrush (properties, collection, &brush)))
			{
				getRenderTarget ()->FillGeometry (geometry, brush);
				brush->Release ();
			}
			collection->Release ();
		}
		geometry->Release ();
		path->Release ();
	}
}
//-----------------------------------------------------------------------------
void D2DDrawContext::fillLinearGradient (CGraphicsPath* _path, const CGradient& gradient, const CPoint& startPoint, const CPoint& endPoint, bool evenOdd, CGraphicsTransform* t)
{
    if (renderTarget == 0)
        return;

    D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path);
    if (d2dPath == 0)
        return;

    ID2D1PathGeometry* path = d2dPath->getPath (evenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING);
    if (path)
    {
        D2DApplyClip ac (this);

        ID2D1Geometry* geometry = 0;
        if (t)
        {
            ID2D1TransformedGeometry* tg = 0;
            D2D1_MATRIX_3X2_F matrix;
            matrix._11 = (FLOAT)t->m11;
            matrix._12 = (FLOAT)t->m12;
            matrix._21 = (FLOAT)t->m21;
            matrix._22 = (FLOAT)t->m22;
            matrix._31 = (FLOAT)t->dx;
            matrix._32 = (FLOAT)t->dy;
            getD2DFactory ()->CreateTransformedGeometry (path, matrix, &tg);
            geometry = tg;
        }
        else
        {
            geometry = path;
            geometry->AddRef ();
        }

        ID2D1GradientStopCollection* collection = 0;
        D2D1_GRADIENT_STOP gradientStops[2];
        gradientStops[0].position = (FLOAT)gradient.getColor1Start ();
        gradientStops[1].position = (FLOAT)gradient.getColor2Start ();
        gradientStops[0].color = D2D1::ColorF (gradient.getColor1 ().red/255.f, gradient.getColor1 ().green/255.f, gradient.getColor1 ().blue/255.f, gradient.getColor1 ().alpha/255.f * currentState.globalAlpha);
        gradientStops[1].color = D2D1::ColorF (gradient.getColor2 ().red/255.f, gradient.getColor2 ().green/255.f, gradient.getColor2 ().blue/255.f, gradient.getColor2 ().alpha/255.f * currentState.globalAlpha);

        if (SUCCEEDED (getRenderTarget ()->CreateGradientStopCollection (gradientStops, 2, &collection)))
        {
            ID2D1LinearGradientBrush* brush = 0;
            D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES properties;
            properties.startPoint = makeD2DPoint (startPoint);
            properties.endPoint = makeD2DPoint (endPoint);
            if (SUCCEEDED (getRenderTarget ()->CreateLinearGradientBrush (properties, collection, &brush)))
            {
                getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Translation ((FLOAT)getOffset ().x, (FLOAT)getOffset ().y));
                getRenderTarget ()->FillGeometry (geometry, brush);
                getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Identity ());
                brush->Release ();
            }
            collection->Release ();
        }

        geometry->Release ();
    }
}
Beispiel #3
0
//-----------------------------------------------------------------------------
void D2DDrawContext::fillLinearGradient (CGraphicsPath* _path, const CGradient& gradient, const CPoint& startPoint, const CPoint& endPoint, bool evenOdd, CGraphicsTransform* t)
{
	if (renderTarget == 0)
		return;

	bool halfPointOffset = currentState.drawMode.integralMode () ? ((((int32_t)currentState.frameWidth) % 2) != 0) : false;
	D2DApplyClip ac (this, halfPointOffset);
	if (ac.isEmpty ())
		return;
	
	D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path);
	if (d2dPath == 0)
		return;

	ID2D1Geometry* path = d2dPath->createPath (evenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING, this, t);
	if (path)
	{

		ID2D1GradientStopCollection* collection = createGradientStopCollection (gradient);
		if (collection)
		{
			ID2D1LinearGradientBrush* brush = 0;
			D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES properties;
			properties.startPoint = makeD2DPoint (startPoint);
			properties.endPoint = makeD2DPoint (endPoint);
			if (SUCCEEDED (getRenderTarget ()->CreateLinearGradientBrush (properties, collection, &brush)))
			{
				getRenderTarget ()->FillGeometry (path, brush);
				brush->Release ();
			}
			collection->Release ();
		}
		path->Release ();
	}
}
void VGraphicPath::SetPosBy(GReal inHoriz, GReal inVert)
{
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	if (!VWinD2DGraphicContext::IsAvailable())
	{
#endif
		Gdiplus::Matrix matrix;
		matrix.Translate(inHoriz, inVert);
		fPath->Transform(&matrix);
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	}
#endif

#if ENABLE_D2D
	if (VWinD2DGraphicContext::IsAvailable() && fPathD2D)
	{
		End();
		
		VAffineTransform mat;
		mat.SetTranslation( inHoriz, inVert);
		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.SetPosBy(inHoriz, inVert);

	if (fComputeBoundsAccurate)
	{
		VPoint translate( (SmallReal)inHoriz, (SmallReal)inVert);

		if (fPathMin != GP_BOUNDS_MIN_DEFAULT)
			fPathMin += translate;
		if (fPathMax != GP_BOUNDS_MAX_DEFAULT)
			fPathMax += translate;
	}
	_ComputeBounds();

	if (fCreateStorageForCrispEdges)
	{
		fDrawCmds.push_back( VGraphicPathDrawCmd( GPDCT_SET_POS_BY, inHoriz, inVert));
		fCurTransform.Translate( inHoriz, inVert, VAffineTransform::MatrixOrderAppend);
	}
}
//-----------------------------------------------------------------------------
void D2DDrawContext::drawGraphicsPath (CGraphicsPath* _path, PathDrawMode mode, CGraphicsTransform* t)
{
    if (renderTarget == 0)
        return;

    D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path);
    if (d2dPath == 0)
        return;

    ID2D1PathGeometry* path = d2dPath->getPath (mode == kPathFilledEvenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING);
    if (path)
    {
        D2DApplyClip ac (this);

        ID2D1Geometry* geometry = 0;
        if (t)
        {
            ID2D1TransformedGeometry* tg = 0;
            D2D1_MATRIX_3X2_F matrix;
            matrix._11 = (FLOAT)t->m11;
            matrix._12 = (FLOAT)t->m12;
            matrix._21 = (FLOAT)t->m21;
            matrix._22 = (FLOAT)t->m22;
            matrix._31 = (FLOAT)t->dx;
            matrix._32 = (FLOAT)t->dy;
            getD2DFactory ()->CreateTransformedGeometry (path, matrix, &tg);
            geometry = tg;
        }
        else
        {
            geometry = path;
            geometry->AddRef ();
        }

        getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Translation ((FLOAT)getOffset ().x, (FLOAT)getOffset ().y));

        if (mode == kPathFilled || mode == kPathFilledEvenOdd)
            getRenderTarget ()->FillGeometry (geometry, getFillBrush ());
        else if (mode == kPathStroked)
            getRenderTarget ()->DrawGeometry (geometry, getStrokeBrush (), (FLOAT)getLineWidth (), getStrokeStyle ());

        getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Identity ());

        geometry->Release ();
    }
}
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();
	}
}
Beispiel #7
0
//-----------------------------------------------------------------------------
void D2DDrawContext::drawGraphicsPath (CGraphicsPath* _path, PathDrawMode mode, CGraphicsTransform* t)
{
	if (renderTarget == 0)
		return;

	bool halfPointOffset = (mode == kPathStroked || currentState.drawMode.integralMode ()) ? ((((int32_t)currentState.frameWidth) % 2) != 0) : false;
	D2DApplyClip ac (this, halfPointOffset);
	if (ac.isEmpty ())
		return;

	D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path);
	if (d2dPath == 0)
		return;

	ID2D1Geometry* path = d2dPath->createPath (mode == kPathFilledEvenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING, currentState.drawMode.integralMode () ? this : 0, t);
	if (path)
	{
		if (mode == kPathFilled || mode == kPathFilledEvenOdd)
			getRenderTarget ()->FillGeometry (path, getFillBrush ());
		else if (mode == kPathStroked)
			getRenderTarget ()->DrawGeometry (path, getStrokeBrush (), (FLOAT)getLineWidth (), getStrokeStyle ());
		path->Release ();
	}
}
/** 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();
	}
}