// 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; }
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); }
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)); }
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)); }
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 }
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)); }
/* 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); } }
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; }