private void AddPath (CCVector2[] points, int offset, int count, Pen pen, PenWorkspace ws) { RequestBufferSpace(count * 2, (count - 1) * 6); _ws.ResetWorkspace(pen); AddInfo(PrimitiveType.TriangleList, count * 2, (count - 1) * 6, pen.Brush); int baseVertexIndex = _vertexBufferIndex; AddStartPoint(points[offset + 0], points[offset + 1], pen, _ws); JoinSample js = new JoinSample(CCVector2.Zero, points[offset + 0], points[offset + 1]); for (int i = 0; i < count - 2; i++) { js.Advance(points[offset + i + 2]); AddMiteredJoint(ref js, pen, ws); } AddEndPoint(points[offset + count - 2], points[offset + count - 1], pen, _ws); for (int i = 0; i < count - 1; i++) AddSegment(baseVertexIndex + i * 2, baseVertexIndex + (i + 1) * 2); }
private void CompileOpenPath (IList<Vector2> points, IList<float> accumLengths, int offset, int count, Pen outlinePen) { if (_strokeType != StrokeType.Outline) InitializeBuffers(count); IList<float> lengths = accumLengths ?? _zeroList; Buffer<Vector2> insetBuffer = null; Buffer<Vector2> outsetBuffer = null; if (outlinePen != null && _strokeType != StrokeType.Fill) { insetBuffer = Pools<Buffer<Vector2>>.Obtain(); outsetBuffer = Pools<Buffer<Vector2>>.Obtain(); int vCount = _positionData != null ? _positionData.Length : _pen.MaximumVertexCount(count); insetBuffer.EnsureCapacity(vCount); outsetBuffer.EnsureCapacity(vCount); } PenWorkspace ws = Pools<PenWorkspace>.Obtain(); ws.ResetWorkspace(_pen); ws.PathLength = lengths[offset + count - 1]; int vPrevCount = 0; int vNextCount = AddStartPoint(0, points[offset + 0], points[offset + 1], ws, insetBuffer); if (insetBuffer != null) Array.Reverse(insetBuffer.Data, 0, insetBuffer.Index); JoinSample joinSample = new JoinSample(Vector2.Zero, points[offset + 0], points[offset + 1], 0, lengths[offset + 0], lengths[offset + 1]); for (int i = 0; i < count - 2; i++) { joinSample.Advance(points[offset + i + 2], lengths[offset + i + 2]); vPrevCount = vNextCount; vNextCount = AddJoint(i + 1, ref joinSample, ws, insetBuffer, outsetBuffer); if (_strokeType != StrokeType.Outline) AddSegment(_vertexBufferIndex - vNextCount - vPrevCount, vPrevCount, _jointCCW[i], _vertexBufferIndex - vNextCount, vNextCount, _jointCCW[i + 1]); } /*for (int i = 0; i < count - 2; i++) { int i0 = offset + i; int i1 = i0 + 1; int i2 = i0 + 2; vPrevCount = vNextCount; vNextCount = AddJoint(i + 1, points[i0], points[i1], points[i2], lengths[i0], lengths[i1], lengths[i2], ws, insetBuffer, outsetBuffer); if (_strokeType != StrokeType.Outline) AddSegment(_vertexBufferIndex - vNextCount - vPrevCount, vPrevCount, _jointCCW[i], _vertexBufferIndex - vNextCount, vNextCount, _jointCCW[i + 1]); }*/ vPrevCount = vNextCount; vNextCount = AddEndPoint(count - 1, points[offset + count - 2], points[offset + count - 1], ws, insetBuffer); if (_strokeType != StrokeType.Outline) AddSegment(_vertexBufferIndex - vNextCount - vPrevCount, vPrevCount, _jointCCW[count - 2], _vertexBufferIndex - vNextCount, vNextCount, _jointCCW[count - 1]); if (insetBuffer != null) Array.Reverse(insetBuffer.Data, 0, insetBuffer.Index); Pools<PenWorkspace>.Release(ws); if (outlinePen != null && _strokeType != StrokeType.Fill) { Buffer<Vector2> mergedBuffer = Pools<Buffer<Vector2>>.Obtain(); mergedBuffer.EnsureCapacity(insetBuffer.Index + outsetBuffer.Index); Array.Copy(insetBuffer.Data, 0, mergedBuffer.Data, 0, insetBuffer.Index); Array.Copy(outsetBuffer.Data, 0, mergedBuffer.Data, insetBuffer.Index, outsetBuffer.Index); _outlinePaths = new GraphicsPath[] { new GraphicsPath(outlinePen, mergedBuffer.Data, PathType.Closed, 0, insetBuffer.Index + outsetBuffer.Index), }; Pools<Buffer<Vector2>>.Release(mergedBuffer); Pools<Buffer<Vector2>>.Release(insetBuffer); Pools<Buffer<Vector2>>.Release(outsetBuffer); } }
private void CompileClosedPath (IList<Vector2> points, IList<float> accumLengths, int offset, int count, Pen outlinePen) { if (_strokeType != StrokeType.Outline) InitializeBuffers(count + 1); if (IsClose(points[offset], points[offset + count - 1])) count--; IList<float> lengths = accumLengths ?? _zeroList; Buffer<Vector2> insetBuffer = null; Buffer<Vector2> outsetBuffer = null; if (outlinePen != null && _strokeType != StrokeType.Fill) { insetBuffer = Pools<Buffer<Vector2>>.Obtain(); outsetBuffer = Pools<Buffer<Vector2>>.Obtain(); int vCount = _positionData != null ? _positionData.Length : _pen.MaximumVertexCount(count); insetBuffer.EnsureCapacity(vCount); outsetBuffer.EnsureCapacity(vCount); } PenWorkspace ws = Pools<PenWorkspace>.Obtain(); ws.ResetWorkspace(_pen); JoinSample joinSample = new JoinSample(points[offset + count - 1], points[offset + 0], points[offset + 1], 0, lengths[offset + 0], lengths[offset + 1]); int vBaseIndex = _vertexBufferIndex; int vBaseCount = AddJoint(0, ref joinSample, ws, insetBuffer, outsetBuffer); int vPrevCount = 0; int vNextCount = vBaseCount; for (int i = 0; i < count - 2; i++) { joinSample.Advance(points[offset + i + 2], lengths[offset + i + 2]); vPrevCount = vNextCount; vNextCount = AddJoint(i + 1,ref joinSample, ws, insetBuffer, outsetBuffer); if (_strokeType != StrokeType.Outline) AddSegment(_vertexBufferIndex - vNextCount - vPrevCount, vPrevCount, _jointCCW[i], _vertexBufferIndex - vNextCount, vNextCount, _jointCCW[i + 1]); } joinSample.Advance(points[offset + 0], lengths[offset + 0]); vPrevCount = vNextCount; vNextCount = AddJoint(count - 1, ref joinSample, ws, insetBuffer, outsetBuffer); if (_strokeType != StrokeType.Outline) { AddSegment(_vertexBufferIndex - vNextCount - vPrevCount, vPrevCount, _jointCCW[count - 2], _vertexBufferIndex - vNextCount, vNextCount, _jointCCW[count - 1]); AddSegment(_vertexBufferIndex - vNextCount, vNextCount, _jointCCW[count - 1], vBaseIndex, vBaseCount, _jointCCW[0]); } Pools<PenWorkspace>.Release(ws); if (outlinePen != null && _strokeType != StrokeType.Fill) { Array.Reverse(insetBuffer.Data, 0, insetBuffer.Index); _outlinePaths = new GraphicsPath[] { new GraphicsPath(outlinePen, insetBuffer.Data, PathType.Closed, 0, insetBuffer.Index), new GraphicsPath(outlinePen, outsetBuffer.Data, PathType.Closed, 0, outsetBuffer.Index), }; Pools<Buffer<Vector2>>.Release(insetBuffer); Pools<Buffer<Vector2>>.Release(outsetBuffer); } }
/// <summary> /// Computes and adds a quadrilateral path to the batch of figures to be rendered. /// </summary> /// <param name="pen">The pen to render the path with.</param> /// <param name="points">An array containing the coordinates of the quad.</param> /// <param name="offset">The offset into the points array.</param> /// <param name="angle">The angle to rotate the quad by around its weighted center in radians. Positive values rotate clockwise.</param> /// <exception cref="InvalidOperationException"><c>DrawQuad</c> was called, but <see cref="Begin()"/> has not yet been called.</exception> public void DrawQuad (Pen pen, Vector2[] points, int offset, float angle) { if (!_inDraw) throw new InvalidOperationException(); if (pen == null) throw new ArgumentNullException("pen"); if (points == null) throw new ArgumentNullException("points"); if (points.Length < offset + 4) throw new ArgumentException("Points array is too small for the given offset."); RequestBufferSpace(8, 24); _ws.ResetWorkspace(pen); AddInfo(PrimitiveType.TriangleList, 8, 24, pen.Brush); if (points != _geometryBuffer) Array.Copy(points, _geometryBuffer, 4); if (angle != 0) { float centerX = (_geometryBuffer[0].X + _geometryBuffer[1].X + _geometryBuffer[2].X + _geometryBuffer[3].X) / 4; float centerY = (_geometryBuffer[0].Y + _geometryBuffer[1].Y + _geometryBuffer[2].Y + _geometryBuffer[3].Y) / 4; Vector2 center = new Vector2(centerX, centerY); Matrix transform = Matrix.CreateRotationZ(angle); transform.Translation = new Vector3(center, 0); for (int i = 0; i < 4; i++) _geometryBuffer[i] = Vector2.Transform(_geometryBuffer[i] - center, transform); } int baseVertexIndex = _vertexBufferIndex; JoinSample js = new JoinSample(_geometryBuffer[0], _geometryBuffer[1], _geometryBuffer[2]); AddMiteredJoint(ref js, pen, _ws); js.Advance(_geometryBuffer[3]); AddMiteredJoint(ref js, pen, _ws); js.Advance(_geometryBuffer[0]); AddMiteredJoint(ref js, pen, _ws); js.Advance(_geometryBuffer[1]); AddMiteredJoint(ref js, pen, _ws); AddSegment(baseVertexIndex + 0, baseVertexIndex + 2); AddSegment(baseVertexIndex + 2, baseVertexIndex + 4); AddSegment(baseVertexIndex + 4, baseVertexIndex + 6); AddSegment(baseVertexIndex + 6, baseVertexIndex + 0); if (_sortMode == DrawSortMode.Immediate) FlushBuffer(); }