Ejemplo n.º 1
0
//-----------------------------------------------------------------------------
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 ();
    }
}
Ejemplo n.º 2
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 ();
	}
}
Ejemplo n.º 3
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 ();
	}
}
Ejemplo n.º 4
0
//-----------------------------------------------------------------------------
void D2DDrawContext::drawEllipse (const CRect &_rect, const CDrawStyle drawStyle)
{
	if (renderTarget == 0)
		return;
	D2DApplyClip ac (this);
	if (ac.isEmpty ())
		return;
	CRect rect (_rect);
	if (currentState.drawMode.integralMode ())
		pixelAllign (rect);
	CPoint center (rect.getTopLeft ());
	center.offset (rect.getWidth () / 2., rect.getHeight () / 2.);
	D2D1_ELLIPSE ellipse;
	ellipse.point = makeD2DPoint (center);
	ellipse.radiusX = (FLOAT)(rect.getWidth () / 2.);
	ellipse.radiusY = (FLOAT)(rect.getHeight () / 2.);
	if (drawStyle == kDrawFilled || drawStyle == kDrawFilledAndStroked)
	{
		renderTarget->FillEllipse (ellipse, fillBrush);
	}
	if (drawStyle == kDrawStroked || drawStyle == kDrawFilledAndStroked)
	{
		renderTarget->DrawEllipse (ellipse, strokeBrush, (FLOAT)currentState.frameWidth, strokeStyle);
	}
}
Ejemplo n.º 5
0
//-----------------------------------------------------------------------------
void D2DDrawContext::lineTo (const CPoint &point)
{
    CPoint penLocation (currentState.penLoc);
    CPoint p (point);
    p.offset (currentState.offset.x, currentState.offset.y);
    if (currentState.drawMode.integralMode ())
    {
        p.makeIntegral ();
        penLocation.makeIntegral ();
    }

    if (renderTarget)
    {
        D2DApplyClip clip (this);
        if ((((int32_t)currentState.frameWidth) % 2))
            renderTarget->SetTransform (D2D1::Matrix3x2F::Translation (0.5f, 0.5f));
        renderTarget->DrawLine (makeD2DPoint (penLocation), makeD2DPoint (p), strokeBrush, (FLOAT)currentState.frameWidth, strokeStyle);
        renderTarget->SetTransform (D2D1::Matrix3x2F::Identity ());
    }
    currentState.penLoc = p;
}
Ejemplo n.º 6
0
//-----------------------------------------------------------------------------
void D2DDrawContext::drawLine (const LinePair& line)
{
	if (renderTarget == 0)
		return;
	D2DApplyClip ac (this, (((int32_t)currentState.frameWidth) % 2) != 0);
	if (ac.isEmpty ())
		return;
	
	if (renderTarget)
	{
		CPoint start (line.first);
		CPoint end (line.second);
		if (currentState.drawMode.integralMode ())
		{
			pixelAllign (start);
			pixelAllign (end);
		}

		renderTarget->DrawLine (makeD2DPoint (start), makeD2DPoint (end), strokeBrush, (FLOAT)currentState.frameWidth, strokeStyle);
	}
}
Ejemplo n.º 7
0
//-----------------------------------------------------------------------------
bool D2DGraphicsPath::hitTest (const CPoint& p, bool evenOddFilled, CGraphicsTransform* transform)
{
	ID2D1PathGeometry* _path = getPath (evenOddFilled ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING);
	if (_path)
	{
		D2D1::Matrix3x2F matrix = D2D1::Matrix3x2F::Identity ();
		if (transform)
		{
			matrix._11 = (FLOAT)transform->m11;
			matrix._12 = (FLOAT)transform->m12;
			matrix._21 = (FLOAT)transform->m21;
			matrix._22 = (FLOAT)transform->m22;
			matrix._31 = (FLOAT)transform->dx;
			matrix._32 = (FLOAT)transform->dy;
			
		}
		BOOL result;
		if (SUCCEEDED (_path->FillContainsPoint (makeD2DPoint (p), matrix, &result)))
		{
			return result ? true : false;
		}
	}
	return false;
}
Ejemplo n.º 8
0
//-----------------------------------------------------------------------------
void D2DDrawContext::drawEllipse (const CRect &_rect, const CDrawStyle drawStyle)
{
    if (renderTarget)
    {
        CRect rect (_rect);
        rect.offset (currentState.offset.x, currentState.offset.y);
        rect.normalize ();
        D2DApplyClip clip (this);
        CPoint center (rect.getTopLeft ());
        center.offset (rect.getWidth () / 2., rect.getHeight () / 2.);
        D2D1_ELLIPSE ellipse;
        ellipse.point = makeD2DPoint (center);
        ellipse.radiusX = (FLOAT)(rect.getWidth () / 2.);
        ellipse.radiusY = (FLOAT)(rect.getHeight () / 2.);
        if (drawStyle == kDrawFilled || drawStyle == kDrawFilledAndStroked)
        {
            renderTarget->FillEllipse (ellipse, fillBrush);
        }
        if (drawStyle == kDrawStroked || drawStyle == kDrawFilledAndStroked)
        {
            renderTarget->DrawEllipse (ellipse, strokeBrush, (FLOAT)currentState.frameWidth, strokeStyle);
        }
    }
}
Ejemplo n.º 9
0
//-----------------------------------------------------------------------------
ID2D1PathGeometry* D2DGraphicsPath::getPath (int32_t fillMode)
{
	if (path == 0 || fillMode != currentPathFillMode)
	{
		dirty ();
		if (!SUCCEEDED (getD2DFactory ()->CreatePathGeometry (&path)))
			return 0;
		if (fillMode == -1)
			fillMode = 0;
		currentPathFillMode = fillMode;
		
		ID2D1GeometrySink* sink = 0;
		if (!SUCCEEDED (path->Open (&sink)))
		{
			path->Release ();
			path = 0;
			return 0;
		}

		sink->SetFillMode ((D2D1_FILL_MODE)fillMode);

		bool figureOpen = false;
		CPoint lastPos;
		for (ElementList::const_iterator it = elements.begin (); it != elements.end (); it++)
		{
			Element e = (*it);
			switch (e.type)
			{
				case Element::kArc:
				{
					bool clockwise = e.instruction.arc.clockwise;
					double startAngle = e.instruction.arc.startAngle;
					double endAngle = e.instruction.arc.endAngle;
					CRect o_r (e.instruction.arc.rect.left, e.instruction.arc.rect.top, e.instruction.arc.rect.right, e.instruction.arc.rect.bottom);
					CRect r (o_r);
					o_r.originize ();
					CPoint center = o_r.getCenter ();
					CPoint start;
					start.x = r.left + center.x + center.x * cos (radians (startAngle));
					start.y = r.top + center.y + center.y * sin (radians (startAngle));
					if (!figureOpen)
					{
						sink->BeginFigure (makeD2DPoint (start), D2D1_FIGURE_BEGIN_FILLED);
						figureOpen = true;
					}
					else if (lastPos != start)
					{
						sink->AddLine (makeD2DPoint (start));
					}

					double sweepangle = endAngle - startAngle;
					if (clockwise) {
						// sweepangle positive
						while (sweepangle < 0.0)
							sweepangle += 360.0;
						while (sweepangle > 360.0)
							sweepangle -= 360.0;
					} else {
						// sweepangle negative
						while (sweepangle > 0.0)
							sweepangle -= 360.0;
						while (sweepangle < -360.0)
							sweepangle += 360.0;
					}

					CPoint endPoint;
					endPoint.x = r.left + center.x + center.x * cos (radians (endAngle));
					endPoint.y = r.top + center.y + center.y * sin (radians (endAngle));

					D2D1_ARC_SEGMENT arc;
					arc.size = makeD2DSize (r.getWidth ()/2., r.getHeight ()/2.);
					arc.rotationAngle = 0;
					arc.sweepDirection = clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE;
					arc.point = makeD2DPoint (endPoint);
					arc.arcSize = fabs(sweepangle) <= 180. ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE;
					sink->AddArc (arc);
					lastPos = endPoint;
					break;
				}
				case Element::kEllipse:
				{
					CRect r (e.instruction.rect.left, e.instruction.rect.top, e.instruction.rect.right, e.instruction.rect.bottom);
					CPoint top (r.getTopLeft ());
					top.x += r.getWidth () / 2.;
					CPoint bottom (r.getBottomLeft ());
					bottom.x += r.getWidth () / 2.;
					if (figureOpen && lastPos != CPoint (e.instruction.rect.left, e.instruction.rect.top))
					{
						sink->EndFigure (D2D1_FIGURE_END_OPEN);
						figureOpen = false;
					}
					if (!figureOpen)
					{
						sink->BeginFigure (makeD2DPoint (top), D2D1_FIGURE_BEGIN_FILLED);
						figureOpen = true;
					}
					D2D1_ARC_SEGMENT arc = D2D1::ArcSegment (makeD2DPoint (bottom), D2D1::SizeF ((FLOAT)r.getWidth ()/2.f, (FLOAT)r.getHeight ()/2.f), 180.f, D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL);
					sink->AddArc (arc);
					arc.point = makeD2DPoint (top);
					sink->AddArc (arc);
					lastPos = top;
					break;
				}
				case Element::kRect:
				{
					D2D1_POINT_2F points[4] = {
						{(FLOAT)e.instruction.rect.right, (FLOAT)e.instruction.rect.top},
						{(FLOAT)e.instruction.rect.right, (FLOAT)e.instruction.rect.bottom},
						{(FLOAT)e.instruction.rect.left, (FLOAT)e.instruction.rect.bottom},
						{(FLOAT)e.instruction.rect.left, (FLOAT)e.instruction.rect.top}
					};
					if (figureOpen && lastPos != CPoint (e.instruction.rect.left, e.instruction.rect.top))
					{
						sink->EndFigure (D2D1_FIGURE_END_OPEN);
						figureOpen = false;
					}
					if (figureOpen == false)
					{
						sink->BeginFigure (points[3], D2D1_FIGURE_BEGIN_FILLED);
						figureOpen = true;
					}
					sink->AddLine (points[0]);
					sink->AddLine (points[1]);
					sink->AddLine (points[2]);
					sink->AddLine (points[3]);
					lastPos = CPoint (e.instruction.rect.left, e.instruction.rect.top);
					break;
				}
				case Element::kLine:
				{
					if (figureOpen)
					{
						D2D1_POINT_2F end = {(FLOAT)e.instruction.point.x, (FLOAT)e.instruction.point.y};
						sink->AddLine (end);
						lastPos = CPoint (e.instruction.point.x, e.instruction.point.y);
					}
					break;
				}
				case Element::kBezierCurve:
				{
					if (figureOpen)
					{
						D2D1_POINT_2F control1 = {(FLOAT)e.instruction.curve.control1.x, (FLOAT)e.instruction.curve.control1.y};
						D2D1_POINT_2F control2 = {(FLOAT)e.instruction.curve.control2.x, (FLOAT)e.instruction.curve.control2.y};
						D2D1_POINT_2F end = {(FLOAT)e.instruction.curve.end.x, (FLOAT)e.instruction.curve.end.y};
						D2D1_BEZIER_SEGMENT bezier = D2D1::BezierSegment (control1, control2, end);
						sink->AddBezier (bezier);
						lastPos = CPoint (e.instruction.curve.end.x, e.instruction.curve.end.y);
					}
					break;
				}
				case Element::kBeginSubpath:
				{
					if (figureOpen)
						sink->EndFigure (D2D1_FIGURE_END_OPEN);
					D2D1_POINT_2F start = {(FLOAT)e.instruction.point.x, (FLOAT)e.instruction.point.y};
					sink->BeginFigure (start, D2D1_FIGURE_BEGIN_FILLED);
					figureOpen = true;
					lastPos = CPoint (e.instruction.point.x, e.instruction.point.y);
					break;
				}
				case Element::kCloseSubpath:
				{
					if (figureOpen)
					{
						sink->EndFigure (D2D1_FIGURE_END_CLOSED);
						figureOpen = false;
					}
					break;
				}
			}
		}
		if (figureOpen)
			sink->EndFigure (D2D1_FIGURE_END_OPEN);
		HRESULT res = sink->Close ();
		if (!SUCCEEDED (res))
		{
			path->Release ();
			path = 0;
		}
		sink->Release ();
	}
	return path;
}