예제 #1
0
// JM 201206
Boolean VGraphicPath::ScaledHitTest(const VPoint& inPoint, GReal scale) const
{
#if ENABLE_D2D
	if (fPathD2D != NULL)
	{
		BOOL bContains = FALSE;
		fPathD2D->StrokeContainsPoint( D2D1::Point2F(inPoint.GetX(), inPoint.GetY()),
									   4*scale,
									   NULL,
									   NULL,
									   &bContains);
		return bContains == TRUE;
	}
#endif

#if !GRAPHIC_MIXED_GDIPLUS_D2D
	if (!VWinD2DGraphicContext::IsAvailable())
	{
#endif
		Gdiplus::Color black_default_color(0,0,0);
		Gdiplus::Pen p(black_default_color);
		p.SetWidth(4 * scale);
		return fPath->IsOutlineVisible((Gdiplus::REAL)inPoint.GetX(), (Gdiplus::REAL)inPoint.GetY(), &p );
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	}
#endif
	return false;
}
예제 #2
0
bool VRect::HitTest (const VPoint& inPoint) const
{
	return ((inPoint.GetX() - fX) > -kREAL_PIXEL_PRECISION
			&& (inPoint.GetX() - GetRight()) < kREAL_PIXEL_PRECISION
			&& (inPoint.GetY() - fY) > -kREAL_PIXEL_PRECISION
			&& (inPoint.GetY() - GetBottom()) < kREAL_PIXEL_PRECISION);
}
예제 #3
0
void VGraphicPath::BeginSubPathAt(const VPoint& inLocalPoint)
{
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	if (!VWinD2DGraphicContext::IsAvailable())
	{
#endif
		fLastPoint = VPoint((GReal)inLocalPoint.GetX(), (GReal)inLocalPoint.GetY());
		fPath->StartFigure();
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	}
#endif

#if ENABLE_D2D
	if (VWinD2DGraphicContext::IsAvailable())
	{
		if (!fGeomSink)
		{
			Begin();
			if (!fGeomSink)
				return;
		}

		if (!fFigureIsClosed)
			//do not forget to close current figure before opening new figure to prevent really nasty artifacts...
			fGeomSink->EndFigure( D2D1_FIGURE_END_OPEN);
		fGeomSink->BeginFigure( D2D1::Point2F( inLocalPoint.GetX(), inLocalPoint.GetY()),
								   D2D1_FIGURE_BEGIN_FILLED);
		fFigureIsClosed = false;
	}
#endif

	fPolygon.AddPoint(inLocalPoint);

	if (fComputeBoundsAccurate)
		_addPointToBounds( inLocalPoint);
	_ComputeBounds();

	if (fCreateStorageForCrispEdges)
		fDrawCmds.push_back( VGraphicPathDrawCmd( GPDCT_BEGIN_SUBPATH_AT, inLocalPoint));
}
예제 #4
0
void VGraphicPath::AddLineTo(const VPoint& inDestPoint)
{
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	if (!VWinD2DGraphicContext::IsAvailable())
	{
#endif
		Gdiplus::PointF d = Gdiplus::PointF(inDestPoint.GetX(), inDestPoint.GetY());
		fPath->AddLine(Gdiplus::PointF(fLastPoint.x,fLastPoint.y), d);
		fLastPoint.x = d.X;
		fLastPoint.y = d.Y;
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	}
#endif

#if ENABLE_D2D
	if (VWinD2DGraphicContext::IsAvailable())
	{
		if (!fGeomSink)
		{
			Begin();
			if (!fGeomSink)
				return;
		}

		fGeomSink->AddLine( D2D1::Point2F( inDestPoint.GetX(), inDestPoint.GetY()));
	}
#endif

	fPolygon.AddPoint(inDestPoint);

	if (fComputeBoundsAccurate)
		_addPointToBounds( inDestPoint);
	_ComputeBounds();

	if (fCreateStorageForCrispEdges)
		fDrawCmds.push_back( VGraphicPathDrawCmd( GPDCT_ADD_LINE_TO, inDestPoint));
}
예제 #5
0
Boolean VRegion::HitTest (const VPoint& inPoint) const
{
	if (fRegion == NULL) return false;
		
#if !USE_GDIPLUS
	VPoint	testPoint(inPoint);
	testPoint -= fOffset;
	
	if (testPoint.GetX() > kMAX_GDI_RGN_COORD || testPoint.GetY() > kMAX_GDI_RGN_COORD)
		return false;
	else
		return (::PtInRegion(fRegion, testPoint.GetX(), testPoint.GetY()) != 0);
#else
	return fRegion->IsVisible((INT)inPoint.GetX(), (INT)inPoint.GetY());
#endif
}
예제 #6
0
void VGraphicPath::AddBezierTo(const VPoint& inStartControl, const VPoint& inDestPoint, const VPoint& inDestControl)
{
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	if (!VWinD2DGraphicContext::IsAvailable())
	{
#endif
		Gdiplus::PointF d = Gdiplus::PointF(inDestPoint.GetX(), inDestPoint.GetY());
		Gdiplus::PointF c1 = Gdiplus::PointF(inStartControl.GetX(), inStartControl.GetY());
		Gdiplus::PointF c2 = Gdiplus::PointF(inDestControl.GetX(), inDestControl.GetY());
		
		fPath->AddBezier(Gdiplus::PointF(fLastPoint.x,fLastPoint.y), c1, c2, d);
		fLastPoint.x = d.X;
		fLastPoint.y = d.Y;
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	}
#endif

#if ENABLE_D2D
	if (VWinD2DGraphicContext::IsAvailable())
	{
		if (!fGeomSink)
		{
			Begin();
			if (!fGeomSink)
				return;
		}

		D2D1_POINT_2F c1 = D2D1::Point2F(inStartControl.GetX(), inStartControl.GetY());
		D2D1_POINT_2F c2 = D2D1::Point2F(inDestControl.GetX(), inDestControl.GetY());
		D2D1_POINT_2F d = D2D1::Point2F(inDestPoint.GetX(), inDestPoint.GetY());

		fGeomSink->AddBezier( D2D1::BezierSegment(c1, c2, d));
	}
#endif

	fPolygon.AddPoint(inDestPoint);

	if (fComputeBoundsAccurate)
		_addBezierToBounds( inStartControl, inDestControl, inDestPoint);
	_ComputeBounds();

	fHasBezier = true;
	if (fCreateStorageForCrispEdges)
		fDrawCmds.push_back( VGraphicPathDrawCmd( GPDCT_ADD_BEZIER_TO, inStartControl, inDestPoint, inDestControl));
}
예제 #7
0
/* add arc to the specified graphic path
@param inCenter
	arc ellipse center
@param inDestPoint
	dest point of the arc
@param inRX
	arc ellipse radius along x axis
@param inRY
	arc ellipse radius along y axis
	if inRY <= 0, inRY = inRX
@param inLargeArcFlag (default false)
	true for draw largest arc
@param inXAxisRotation (default 0.0f)
	arc x axis rotation in degree
@remarks
	this method add a arc starting from current pos to the dest point 

	use MeasureArc method to get start & end point from ellipse start & end angle in degree
*/
void VGraphicPath::AddArcTo(const VPoint& inCenter, const VPoint& inDestPoint, GReal _inRX, GReal _inRY, bool inLargeArcFlag, GReal inXAxisRotation)
{
	//we need double precision here
	Real inRx = _inRX, inRy = _inRY; 
	Real inX = fLastPoint.x, inY = fLastPoint.y;
	Real inEX = inDestPoint.GetX(), inEY = inDestPoint.GetY();
	
	Real sin_th, cos_th;
    Real a00, a01, a10, a11;
    Real x0, y0, x1, y1, xc, yc;
    Real d, sfactor, sfactor_sq;
    Real th0, th1, th_arc;
    sLONG i, n_segs;
    Real dx, dy, dx1, dy1, Pr1, Pr2, Px, Py, check;

    inRx = fabs(inRx);
    inRy = fabs(inRy);

    sin_th = sin(inXAxisRotation * (PI / 180.0));
    cos_th = cos(inXAxisRotation * (PI / 180.0));

    dx = (inX - inEX) / 2.0;
    dy = (inY - inEY) / 2.0;
    dx1 =  cos_th * dx + sin_th * dy;
    dy1 = -sin_th * dx + cos_th * dy;
    Pr1 = inRx * inRx;
    Pr2 = inRy * inRy;
    Px = dx1 * dx1;
    Py = dy1 * dy1;
    /* Spec : check if radii are large enough */
    check = Px / Pr1 + Py / Pr2;
    if (check > 1) {
        inRx = inRx * sqrt(check);
        inRy = inRy * sqrt(check);
    }

    a00 =  cos_th / inRx;
    a01 =  sin_th / inRx;
    a10 = -sin_th / inRy;
    a11 =  cos_th / inRy;
    x0 = a00 * inX + a01 * inY;
    y0 = a10 * inX + a11 * inY;
    x1 = a00 * inEX + a01 * inEY;
    y1 = a10 * inEX + a11 * inEY;
    xc = a00 * inCenter.GetX() + a01 * inCenter.GetY();
    yc = a10 * inCenter.GetX() + a11 * inCenter.GetY();

    /* (x0, y0) is current point in transformed coordinate space.
       (x1, y1) is new point in transformed coordinate space.
       (xc, yc) is new center in transformed coordinate space.

       The arc fits a unit-radius circle in this space.
    */

	/*
    d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
    sfactor_sq = 1.0 / d - 0.25;
    if (sfactor_sq < 0) sfactor_sq = 0;
    sfactor = sqrt(sfactor_sq);
    if (inSweepFlag == inLargeArcFlag) sfactor = -sfactor;

    xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
    yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
	*/
    /* (xc, yc) is center of the circle. */

    th0 = atan2(y0 - yc, x0 - xc);
    th1 = atan2(y1 - yc, x1 - xc);

    th_arc = th1 - th0;
	if (th0 <= 0.0 && th1 > 0.0 && fabs(th_arc-PI) <= 0.00001)
		th_arc = -th_arc;	//ensure we draw counterclockwise if angle delta = 180°
	else if (fabs(th_arc)-PI > 0.00001 && !inLargeArcFlag)
	{
		if (th_arc > 0)
			th_arc -= 2 * PI;
		else
			th_arc += 2 * PI;
	}
	else if (fabs(th_arc) <= PI && inLargeArcFlag)
	{
		if (th_arc > 0)
			th_arc -= 2 * PI;
		else
			th_arc += 2 * PI;
	}

	//split arc in small arcs <= 90°

    n_segs = int(ceil(fabs(th_arc / (PI * 0.5 + 0.001))));
    for (i = 0; i < n_segs; i++) 
	{
        _PathAddArcSegment(	xc, yc,
							th0 + i * th_arc / n_segs,
							th0 + (i + 1) * th_arc / n_segs,
							inRx, inRy, 
							inXAxisRotation);
    }
}
예제 #8
0
void VRect::SetPosTo (const VPoint& inPos)
{
	SetPosBy(inPos.GetX() - fX, inPos.GetY() - fY);
}
	/** Returns VTRUE if an existing VPoint object has the same
	coordinates as this point, VFALSE otherwise.*/
	VBOOL		IsEqual(VPoint const& pt) const
	{
		return	(pt.GetX() == m_Point.x && pt.GetY() == m_Point.y)
				? VTRUE
				: VFALSE;
	}