internal static partial int GdipAddPathPolygonI( #if NET7_0_OR_GREATER [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef path, Point *points, int count);
public unsafe static extern BOOL Polygon(HDC hdc, Point *apt, int cpt);
internal static extern int GdipAddPathCurveI(HandleRef path, Point *points, int count);
public static unsafe extern bool MoveToEx(HandleRef hdc, int x, int y, Point *lppt);
/// <summary> /// Static method which parses a PathGeometryData and makes calls into the provided context sink. /// This can be used to build a PathGeometry, for readback, etc. /// </summary> internal static void ParsePathGeometryData(PathGeometryData pathData, CapacityStreamGeometryContext ctx) { if (pathData.IsEmpty()) { return; } unsafe { int currentOffset = 0; fixed(byte *pbData = pathData.SerializedData) { // This assert is a logical correctness test Debug.Assert(pathData.Size >= currentOffset + sizeof(MIL_PATHGEOMETRY)); // ... while this assert tests "physical" correctness (i.e. are we running out of buffer). Invariant.Assert(pathData.SerializedData.Length >= currentOffset + sizeof(MIL_PATHGEOMETRY)); MIL_PATHGEOMETRY *pPathGeometry = (MIL_PATHGEOMETRY *)pbData; // Move the current offset to after the Path's data currentOffset += sizeof(MIL_PATHGEOMETRY); // Are there any Figures to add? if (pPathGeometry->FigureCount > 0) { // Allocate the correct number of Figures up front ctx.SetFigureCount((int)pPathGeometry->FigureCount); // ... and iterate on the Figures. for (int i = 0; i < pPathGeometry->FigureCount; i++) { // We only expect well-formed data, but we should assert that we're not reading // too much data. Debug.Assert(pathData.SerializedData.Length >= currentOffset + sizeof(MIL_PATHFIGURE)); MIL_PATHFIGURE *pPathFigure = (MIL_PATHFIGURE *)(pbData + currentOffset); // Move the current offset to the after of the Figure's data currentOffset += sizeof(MIL_PATHFIGURE); ctx.BeginFigure(pPathFigure->StartPoint, ((pPathFigure->Flags & MilPathFigureFlags.IsFillable) != 0), ((pPathFigure->Flags & MilPathFigureFlags.IsClosed) != 0)); if (pPathFigure->Count > 0) { // Allocate the correct number of Segments up front ctx.SetSegmentCount((int)pPathFigure->Count); // ... and iterate on the Segments. for (int j = 0; j < pPathFigure->Count; j++) { // We only expect well-formed data, but we should assert that we're not reading too much data. Debug.Assert(pathData.SerializedData.Length >= currentOffset + sizeof(MIL_SEGMENT)); Debug.Assert(pathData.Size >= currentOffset + sizeof(MIL_SEGMENT)); MIL_SEGMENT *pSegment = (MIL_SEGMENT *)(pbData + currentOffset); switch (pSegment->Type) { case MIL_SEGMENT_TYPE.MilSegmentLine: { // We only expect well-formed data, but we should assert that we're not reading too much data. Debug.Assert(pathData.SerializedData.Length >= currentOffset + sizeof(MIL_SEGMENT_LINE)); Debug.Assert(pathData.Size >= currentOffset + sizeof(MIL_SEGMENT_LINE)); MIL_SEGMENT_LINE *pSegmentLine = (MIL_SEGMENT_LINE *)(pbData + currentOffset); ctx.LineTo(pSegmentLine->Point, ((pSegmentLine->Flags & MILCoreSegFlags.SegIsAGap) == 0), ((pSegmentLine->Flags & MILCoreSegFlags.SegSmoothJoin) != 0)); currentOffset += sizeof(MIL_SEGMENT_LINE); } break; case MIL_SEGMENT_TYPE.MilSegmentBezier: { // We only expect well-formed data, but we should assert that we're not reading too much data. Debug.Assert(pathData.SerializedData.Length >= currentOffset + sizeof(MIL_SEGMENT_BEZIER)); Debug.Assert(pathData.Size >= currentOffset + sizeof(MIL_SEGMENT_BEZIER)); MIL_SEGMENT_BEZIER *pSegmentBezier = (MIL_SEGMENT_BEZIER *)(pbData + currentOffset); ctx.BezierTo(pSegmentBezier->Point1, pSegmentBezier->Point2, pSegmentBezier->Point3, ((pSegmentBezier->Flags & MILCoreSegFlags.SegIsAGap) == 0), ((pSegmentBezier->Flags & MILCoreSegFlags.SegSmoothJoin) != 0)); currentOffset += sizeof(MIL_SEGMENT_BEZIER); } break; case MIL_SEGMENT_TYPE.MilSegmentQuadraticBezier: { // We only expect well-formed data, but we should assert that we're not reading too much data. Debug.Assert(pathData.SerializedData.Length >= currentOffset + sizeof(MIL_SEGMENT_QUADRATICBEZIER)); Debug.Assert(pathData.Size >= currentOffset + sizeof(MIL_SEGMENT_QUADRATICBEZIER)); MIL_SEGMENT_QUADRATICBEZIER *pSegmentQuadraticBezier = (MIL_SEGMENT_QUADRATICBEZIER *)(pbData + currentOffset); ctx.QuadraticBezierTo(pSegmentQuadraticBezier->Point1, pSegmentQuadraticBezier->Point2, ((pSegmentQuadraticBezier->Flags & MILCoreSegFlags.SegIsAGap) == 0), ((pSegmentQuadraticBezier->Flags & MILCoreSegFlags.SegSmoothJoin) != 0)); currentOffset += sizeof(MIL_SEGMENT_QUADRATICBEZIER); } break; case MIL_SEGMENT_TYPE.MilSegmentArc: { // We only expect well-formed data, but we should assert that we're not reading too much data. Debug.Assert(pathData.SerializedData.Length >= currentOffset + sizeof(MIL_SEGMENT_ARC)); Debug.Assert(pathData.Size >= currentOffset + sizeof(MIL_SEGMENT_ARC)); MIL_SEGMENT_ARC *pSegmentArc = (MIL_SEGMENT_ARC *)(pbData + currentOffset); ctx.ArcTo(pSegmentArc->Point, pSegmentArc->Size, pSegmentArc->XRotation, (pSegmentArc->LargeArc != 0), (pSegmentArc->Sweep == 0) ? SweepDirection.Counterclockwise : SweepDirection.Clockwise, ((pSegmentArc->Flags & MILCoreSegFlags.SegIsAGap) == 0), ((pSegmentArc->Flags & MILCoreSegFlags.SegSmoothJoin) != 0)); currentOffset += sizeof(MIL_SEGMENT_ARC); } break; case MIL_SEGMENT_TYPE.MilSegmentPolyLine: case MIL_SEGMENT_TYPE.MilSegmentPolyBezier: case MIL_SEGMENT_TYPE.MilSegmentPolyQuadraticBezier: { // We only expect well-formed data, but we should assert that we're not reading too much data. Debug.Assert(pathData.SerializedData.Length >= currentOffset + sizeof(MIL_SEGMENT_POLY)); Debug.Assert(pathData.Size >= currentOffset + sizeof(MIL_SEGMENT_POLY)); MIL_SEGMENT_POLY *pSegmentPoly = (MIL_SEGMENT_POLY *)(pbData + currentOffset); Debug.Assert(pSegmentPoly->Count <= Int32.MaxValue); if (pSegmentPoly->Count > 0) { List <Point> points = new List <Point>((int)pSegmentPoly->Count); // We only expect well-formed data, but we should assert that we're not reading too much data. Debug.Assert(pathData.SerializedData.Length >= currentOffset + sizeof(MIL_SEGMENT_POLY) + (int)pSegmentPoly->Count * sizeof(Point)); Debug.Assert(pathData.Size >= currentOffset + sizeof(MIL_SEGMENT_POLY) + (int)pSegmentPoly->Count * sizeof(Point)); Point *pPoint = (Point *)(pbData + currentOffset + sizeof(MIL_SEGMENT_POLY)); for (uint k = 0; k < pSegmentPoly->Count; k++) { points.Add(*pPoint); pPoint++; } switch (pSegment->Type) { case MIL_SEGMENT_TYPE.MilSegmentPolyLine: ctx.PolyLineTo(points, ((pSegmentPoly->Flags & MILCoreSegFlags.SegIsAGap) == 0), ((pSegmentPoly->Flags & MILCoreSegFlags.SegSmoothJoin) != 0)); break; case MIL_SEGMENT_TYPE.MilSegmentPolyBezier: ctx.PolyBezierTo(points, ((pSegmentPoly->Flags & MILCoreSegFlags.SegIsAGap) == 0), ((pSegmentPoly->Flags & MILCoreSegFlags.SegSmoothJoin) != 0)); break; case MIL_SEGMENT_TYPE.MilSegmentPolyQuadraticBezier: ctx.PolyQuadraticBezierTo(points, ((pSegmentPoly->Flags & MILCoreSegFlags.SegIsAGap) == 0), ((pSegmentPoly->Flags & MILCoreSegFlags.SegSmoothJoin) != 0)); break; } } currentOffset += sizeof(MIL_SEGMENT_POLY) + (int)pSegmentPoly->Count * sizeof(Point); } break; #if DEBUG case MIL_SEGMENT_TYPE.MilSegmentNone: throw new System.InvalidOperationException(); default: throw new System.InvalidOperationException(); #endif } } } } } } } }
public unsafe List <Point> CubicBezier_GeneratePolyLinePoints(Point startPoint, Point *segmentPoints, int pointCount) { Debug.Assert(pointCount % 3 == 0); var generatedPoints = new List <Point>(); generatedPoints.Add(startPoint); for (var i = 0; i < pointCount; i += 3) { Point p1 = generatedPoints[generatedPoints.Count - 1]; var c1 = segmentPoints[i]; var c2 = segmentPoints[i + 1]; var end = segmentPoints[i + 2]; // Auto-tessellated PathBezierToCasteljau(generatedPoints, p1.X, p1.Y, c1.X, c1.Y, c2.X, c2.Y, end.X, end.Y, CurveTessellationTol, 0); } return(generatedPoints); }
public unsafe static partial BOOL SetViewportOrgEx(HDC hdc, int x, int y, Point *lppt);
private unsafe static extern void SwapByPointer(Point *points, int count);
internal static extern int GdipAddPathCurve3I(HandleRef path, Point *points, int count, int offset, int numberOfSegments, float tension);
unsafe static void Do2(Point *src, Point *dst) { *((long *)dst) = *((long *)src); }
public unsafe static extern BOOL SetWindowOrgEx(HDC hdc, int x, int y, Point *lppt);
unsafe static void Do1(Point *src, Point *dst) { *((Point *)dst) = *((Point *)src); }
public static unsafe extern bool GetViewportOrgEx(IntPtr hdc, Point *p);
private unsafe void CreateMiniMapTexture(bool force = false) { if (_gumpTexture == null || _gumpTexture.IsDisposed) { return; } ushort lastX = World.Player.X; ushort lastY = World.Player.Y; if (_x != lastX || _y != lastY) { _x = lastX; _y = lastY; } else if (!force) { return; } int blockOffsetX = Width >> 2; int blockOffsetY = Height >> 2; int gumpCenterX = Width >> 1; //int gumpCenterY = Height >> 1; //0xFF080808 - pixel32 //0x8421 - pixel16 int minBlockX = ((lastX - blockOffsetX) >> 3) - 1; int minBlockY = ((lastY - blockOffsetY) >> 3) - 1; int maxBlockX = ((lastX + blockOffsetX) >> 3) + 1; int maxBlockY = ((lastY + blockOffsetY) >> 3) + 1; if (minBlockX < 0) { minBlockX = 0; } if (minBlockY < 0) { minBlockY = 0; } int maxBlockIndex = World.Map.BlocksCount; int mapBlockHeight = MapLoader.Instance.MapBlocksSize[World.MapIndex, 1]; int index = _useLargeMap ? 1 : 0; _blankGumpsPixels[index].CopyTo(_blankGumpsPixels[index + 2], 0); uint[] data = _blankGumpsPixels[index + 2]; Point *table = stackalloc Point[2]; table[0].X = 0; table[0].Y = 0; table[1].X = 0; table[1].Y = 1; for (int i = minBlockX; i <= maxBlockX; i++) { int blockIndexOffset = i * mapBlockHeight; for (int j = minBlockY; j <= maxBlockY; j++) { int blockIndex = blockIndexOffset + j; if (blockIndex >= maxBlockIndex) { break; } RadarMapBlock?mbbv = MapLoader.Instance.GetRadarMapBlock(World.MapIndex, i, j); if (!mbbv.HasValue) { break; } RadarMapBlock mb = mbbv.Value; Chunk block = World.Map.Chunks[blockIndex]; int realBlockX = i << 3; int realBlockY = j << 3; for (int x = 0; x < 8; x++) { int px = realBlockX + x - lastX + gumpCenterX; for (int y = 0; y < 8; y++) { int py = realBlockY + y - lastY; int gx = px - py; int gy = px + py; int color = mb.Cells[x, y].Graphic; bool island = mb.Cells[x, y].IsLand; if (block != null) { GameObject obj = block.Tiles[x, y]; while (obj?.TNext != null) { obj = obj.TNext; } for (; obj != null; obj = obj.TPrevious) { if (obj is Multi) { if (obj.Hue == 0) { color = obj.Graphic; island = false; } else { color = obj.Hue + 0x4000; } break; } } } if (!island) { color += 0x4000; } int tableSize = 2; if (island && color > 0x4000) { color = HuesLoader.Instance.GetColor16(16384, (ushort)(color - 0x4000)); //28672 is an arbitrary position in hues.mul, is the 14 position in the range } else { color = HuesLoader.Instance.GetRadarColorData(color); } CreatePixels ( data, 0x8000 | color, gx, gy, Width, Height, table, tableSize ); } } } } if (_mapTexture == null || _mapTexture.IsDisposed) { _mapTexture = new UOTexture(Width, Height); } _mapTexture.PushData(data); }
/// <summary> /// Add a poly line. /// </summary> /// <param name="points">pointer to points data</param> /// <param name="pointsCount">number of points</param> /// <param name="color">color</param> /// <param name="close">Should this method close the polyline for you? A line segment from the last point to first point will be added if this is true.</param> /// <param name="thickness">thickness</param> /// <param name="antiAliased">anti-aliased</param> public unsafe void AddPolyline(Point *points, int pointsCount, Color color, bool close, double thickness, bool antiAliased = false) { AddPolyline(points, pointsCount, Vector.Zero, color, close, thickness, antiAliased); }
internal static extern int GdipAddPathPolygonI(HandleRef path, Point *points, int count);
/// <summary> /// Add a poly line with offset. /// </summary> /// <param name="points">pointer to points data</param> /// <param name="pointsCount">number of points</param> /// <param name="offset">offset that applies to every point</param> /// <param name="color">color</param> /// <param name="close">Should this method close the polyline for you? A line segment from the last point to first point will be added if this is true.</param> /// <param name="thickness">thickness</param> /// <param name="antiAliased">anti-aliased</param> public unsafe void AddPolyline(Point *points, int pointsCount, Vector offset, Color color, bool close, double thickness, bool antiAliased = false) { if (pointsCount < 2) { return; } int count = pointsCount; if (!close) { count = pointsCount - 1; } if (antiAliased) { throw new NotImplementedException(); } else { // Non Anti-aliased Stroke int idxCount = count * 6; int vtxCount = count * 4; // FIXME: Not sharing edges this.ShapeMesh.PrimReserve(idxCount, vtxCount); for (int i1 = 0; i1 < count; i1++) { int i2 = (i1 + 1) == pointsCount ? 0 : i1 + 1; Point p1 = points[i1]; Point p2 = points[i2]; double dx = p2.x - p1.x; double dy = p2.y - p1.y; MathEx.NORMALIZE2F_OVER_ZERO(ref dx, ref dy); dx *= (thickness * 0.5); dy *= (thickness * 0.5); p1 += offset; p2 += offset; var vertex0 = new DrawVertex { pos = new Point(p1.X + dy, p1.Y - dx), uv = Point.Zero, color = color }; var vertex1 = new DrawVertex { pos = new Point(p2.X + dy, p2.Y - dx), uv = Point.Zero, color = color }; var vertex2 = new DrawVertex { pos = new Point(p2.X - dy, p2.Y + dx), uv = Point.Zero, color = color }; var vertex3 = new DrawVertex { pos = new Point(p1.X - dy, p1.Y + dx), uv = Point.Zero, color = color }; this.ShapeMesh.AppendVertex(vertex0); this.ShapeMesh.AppendVertex(vertex1); this.ShapeMesh.AppendVertex(vertex2); this.ShapeMesh.AppendVertex(vertex3); this.ShapeMesh.AppendIndex(0); this.ShapeMesh.AppendIndex(1); this.ShapeMesh.AppendIndex(2); this.ShapeMesh.AppendIndex(0); this.ShapeMesh.AppendIndex(2); this.ShapeMesh.AppendIndex(3); this.ShapeMesh.currentIdx += 4; } } }
internal static extern int GdipDrawBeziersI(HandleRef graphics, HandleRef pen, Point *points, int count);
public unsafe List <Point> QuadraticBezier_GeneratePolyLinePoints(Point startPoint, Point *segmentPoints, int pointCount) { Debug.Assert(pointCount % 2 == 0); var generatedPoints = new List <Point>(); generatedPoints.Add(startPoint); for (var i = 0; i < pointCount; i += 2) { Point start = generatedPoints[generatedPoints.Count - 1];//start point //convert quaratic bezier segment points to cubic bezier segment points var x0 = start.X; var y0 = start.Y; var x1 = segmentPoints[i].X; var y1 = segmentPoints[i].Y; var x2 = segmentPoints[i + 1].X; var y2 = segmentPoints[i + 1].Y; var c1 = new Point(2.0 / 3.0 * x1 + 1.0 / 3.0 * x0, 2.0 / 3.0 * y1 + 1.0 / 3.0 * y0); //control point 1 var c2 = new Point(2.0 / 3.0 * x1 + 1.0 / 3.0 * x2, 2.0 / 3.0 * y1 + 1.0 / 3.0 * y2); //control point 2 var end = new Point(x2, y2); //end point // Auto-tessellated PathBezierToCasteljau(generatedPoints, start.X, start.Y, c1.X, c1.Y, c2.X, c2.Y, end.X, end.Y, CurveTessellationTol, 0); } return(generatedPoints); }
internal static extern int GdipEnumerateMetafileDestPointsI(HandleRef graphics, HandleRef metafile, Point *destPoints, int count, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, HandleRef imageattributes);
static void Main() { unsafe { // Note: Доступ к указателям int x = 0; int *pX = &x; * pX = 13; Console.WriteLine("x = {0}", x); Point pt; Point *pPt = &pt; pPt->X = 13; pPt->Y = 14; pPt->Offset(1, 2); Console.WriteLine("pt = {0}", pt); // ReSharper disable once UnusedVariable List <object> list = new List <object>(); //List<object>* pList = &list;//won't compile! // Note: Ускорение доступа к массивам const int size = 10; int[] vals = new int[size]; try { for (int i = 0; i < size + 1; i++) { vals[i] = i; } } catch (IndexOutOfRangeException ex) { Console.WriteLine("Caught exception: " + ex.Message); } // Арифметика указателей Console.WriteLine("Pointer arithmetic"); fixed(int *pI = &vals[0]) { int *pA = pI; while (*pA < 8) { // Увеличить на 2 * sizeof(element) pA += 2; Console.WriteLine("*pA = {0}", *pA); } } // Note: Предотвращение перемещения объектов в памяти Console.WriteLine("Going out of bounds"); // Местоположение значений зафиксировано на время выполнения блока fixed(int *pI = &vals[0]) { // Какая досада! Мы зашли слишком далеко и испортили данные // в памяти, которая нам не принадлежит for (int i = 0; i < size + 1; i++) { pI[i] = i; } Console.WriteLine("No exception thrown! We just overwrote memory we shouldn't have!"); } } Console.ReadKey(); }
internal static extern int GdipEnumerateMetafileSrcRectDestPointsI(HandleRef graphics, HandleRef metafile, Point *destPoints, int count, ref Rectangle srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, HandleRef imageattributes);
public static unsafe extern bool SetViewportOrgEx(HandleRef hDC, int x, int y, Point *point);
internal static extern int GdipCreatePath2I(Point *points, byte *types, int count, int brushMode, out IntPtr path);
internal unsafe static Rect GetBoundsHelper( Pen pen, Matrix *pWorldMatrix, Point *pPoints, byte *pTypes, uint pointCount, uint segmentCount, Matrix *pGeometryMatrix, double tolerance, ToleranceType type, bool fSkipHollows) { MIL_PEN_DATA penData; double[] dashArray = null; // If the pen contributes to the bounds, populate the CMD struct bool fPenContributesToBounds = Pen.ContributesToBounds(pen); if (fPenContributesToBounds) { pen.GetBasicPenData(&penData, out dashArray); } MilMatrix3x2D geometryMatrix; if (pGeometryMatrix != null) { geometryMatrix = CompositionResourceManager.MatrixToMilMatrix3x2D(ref (*pGeometryMatrix)); } Debug.Assert(pWorldMatrix != null); MilMatrix3x2D worldMatrix = CompositionResourceManager.MatrixToMilMatrix3x2D(ref (*pWorldMatrix)); Rect bounds; fixed(double *pDashArray = dashArray) { int hr = MilCoreApi.MilUtility_PolygonBounds( &worldMatrix, (fPenContributesToBounds) ? &penData : null, (dashArray == null) ? null : pDashArray, pPoints, pTypes, pointCount, segmentCount, (pGeometryMatrix == null) ? null : &geometryMatrix, tolerance, type == ToleranceType.Relative, fSkipHollows, &bounds ); if (hr == (int)MILErrors.WGXERR_BADNUMBER) { // When we encounter NaNs in the renderer, we absorb the error and draw // nothing. To be consistent, we report that the geometry has empty bounds. bounds = Rect.Empty; } else { HRESULT.Check(hr); } } return(bounds); }
public unsafe static extern BOOL OffsetViewportOrgEx(HDC hdc, int x, int y, Point *lppt);
internal static extern int GdipAddPathBeziersI(HandleRef path, Point *points, int count);
public static extern unsafe int core_Mat_nGetPoint(IntPtr obj, int row, int col, Point *vals, int valsLength);
internal static extern int GdipAddPathCurve2I(HandleRef path, Point *points, int count, float tension);
internal static partial int GdipAddPathClosedCurve2I( #if NET7_0_OR_GREATER [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef path, Point *points, int count, float tension);