//======= Crossings Multiply algorithm of InsideTest ======================== // // By Eric Haines, 3D/Eye Inc, [email protected] // // This version is usually somewhat faster than the original published in // Graphics Gems IV; by turning the division for testing the X axis crossing // into a tricky multiplication test this part of the test became faster, // which had the additional effect of making the test for "both to left or // both to right" a bit slower for triangles than simply computing the // intersection each time. The main increase is in triangle testing speed, // which was about 15% faster; all other polygon complexities were pretty much // the same as before. On machines where division is very expensive (not the // case on the HP 9000 series on which I tested) this test should be much // faster overall than the old code. Your mileage may (in fact, will) vary, // depending on the machine and the test data, but in general I believe this // code is both shorter and faster. This test was inspired by unpublished // Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson. // Related work by Samosky is in: // // Samosky, Joseph, "SectionView: A system for interactively specifying and // visualizing sections through three-dimensional medical image data", // M.S. Thesis, Department of Electrical Engineering and Computer Science, // Massachusetts Institute of Technology, 1993. // // Shoot a test ray along +X axis. The strategy is to compare vertex Y values // to the testing point's Y and quickly discard edges which are entirely to one // side of the test ray. Note that CONVEX and WINDING code can be added as // for the CrossingsTest() code; it is left out here for clarity. // // Input 2D polygon _pgon_ with _numverts_ number of vertices and test point // _point_, returns 1 if inside, 0 if outside. public static bool IsPointInVxs(VertexStore vxs, double tx, double ty) { int m_num_points = vxs.Count; if (m_num_points < 3) return false; // if (!m_in_polygon_check) return false; int j; bool yflag0, yflag1, inside_flag; double vtx0, vty0, vtx1, vty1; vxs.GetVertex(m_num_points, out vtx0, out vty0); //vtx0 = GetXN(m_num_points - 1); //vty0 = GetYN(m_num_points - 1); // get test bit for above/below X axis yflag0 = (vty0 >= ty); //vtx1 = GetXN(0); //vty1 = GetYN(0); vxs.GetVertex(0, out vtx1, out vty1); inside_flag = false; for (j = 1; j <= m_num_points; ++j) { yflag1 = (vty1 >= ty); // Check if endpoints straddle (are on opposite sides) of X axis // (i.e. the Y's differ); if so, +X ray could intersect this edge. // The old test also checked whether the endpoints are both to the // right or to the left of the test point. However, given the faster // intersection point computation used below, this test was found to // be a break-even proposition for most polygons and a loser for // triangles (where 50% or more of the edges which survive this test // will cross quadrants and so have to have the X intersection computed // anyway). I credit Joseph Samosky with inspiring me to try dropping // the "both left or both right" part of my code. if (yflag0 != yflag1) { // Check intersection of pgon segment with +X ray. // Note if >= point's X; if so, the ray hits it. // The division operation is avoided for the ">=" test by checking // the sign of the first vertex wrto the test point; idea inspired // by Joseph Samosky's and Mark Haigh-Hutchinson's different // polygon inclusion tests. if (((vty1 - ty) * (vtx0 - vtx1) >= (vtx1 - tx) * (vty0 - vty1)) == yflag1) { inside_flag = !inside_flag; } } // Move to the next pair of vertices, retaining info as possible. yflag0 = yflag1; vtx0 = vtx1; vty0 = vty1; int k = (j >= m_num_points) ? j - m_num_points : j; //vtx1 = GetXN(k); //vty1 = GetYN(k); vxs.GetVertex(k, out vtx1, out vty1); } return inside_flag; }
public VertexStore MakeVxs(VertexStore sourceVxs, VertexStore vxs) { StrokeGenerator strkgen = strokeGen; int j = sourceVxs.Count; double x, y; strkgen.RemoveAll(); //1st vertex sourceVxs.GetVertex(0, out x, out y); strkgen.AddVertex(x, y, VertexCmd.MoveTo); double startX = x, startY = y; bool hasMoreThanOnePart = false; for (int i = 0; i < j; ++i) { var cmd = sourceVxs.GetVertex(i, out x, out y); switch (cmd) { case VertexCmd.Stop: break; case VertexCmd.EndFigure: case VertexCmd.CloseAndEndFigure: { strkgen.AddVertex(x, y, cmd); if (i < j - 2) { strkgen.AddVertex(startX, startY, VertexCmd.LineTo); strkgen.WriteTo(vxs); strkgen.RemoveAll(); hasMoreThanOnePart = true; } //end this polygon } break; case VertexCmd.LineTo: case VertexCmd.P2c: case VertexCmd.P3c: { strkgen.AddVertex(x, y, cmd); } break; case VertexCmd.MoveTo: { strkgen.AddVertex(x, y, cmd); startX = x; startY = y; } break; default: throw new System.NotSupportedException(); } } strkgen.WriteTo(vxs); strkgen.RemoveAll(); vxs.HasMoreThanOnePart = hasMoreThanOnePart; return vxs; }
public VertexStore MakeVxs(VertexStore output) { PathWriter m_LinesToDraw = new PathWriter(output); m_LinesToDraw.Clear(); m_LinesToDraw.MoveTo(bounds.Left, bounds.Bottom); m_LinesToDraw.LineTo(bounds.Right, bounds.Bottom); m_LinesToDraw.LineTo(bounds.Right, bounds.Top); m_LinesToDraw.LineTo(bounds.Left, bounds.Top); m_LinesToDraw.CloseFigure(); return m_LinesToDraw.Vxs; }
public ContourGenerator() { m_stroker = new StrokeMath(); m_width = 1; vertexDistanceList = new VertexDistanceList(); m_out_vertices = new VertexStore(); m_status = StrokeMath.Status.Init; m_src_vertex = 0; m_closed = false; m_orientation = 0; m_auto_detect = false; }
//---------------------------------- static bool GetBoundingRect(VertexStore vxs, int[] gi, int num, out double x1, out double y1, out double x2, out double y2) { int i; double x = 0; double y = 0; bool first = true; x1 = 1; y1 = 1; x2 = 0; y2 = 0; int iterindex = 0; for (i = 0; i < num; i++) { VertexCmd flags; while ((flags = vxs.GetVertex(iterindex++, out x, out y)) != VertexCmd.Stop) { switch (flags) { //if is vertext cmd case VertexCmd.LineTo: case VertexCmd.MoveTo: case VertexCmd.P2c: case VertexCmd.P3c: { if (first) { x1 = x; y1 = y; x2 = x; y2 = y; first = false; } else { if (x < x1) x1 = x; if (y < y1) y1 = y; if (x > x2) x2 = x; if (y > y2) y2 = y; } } break; } } } return x1 <= x2 && y1 <= y2; }
public static void RenderSolidAllPaths(this ScanlineRasToDestBitmapRenderer sclineRasToBmp, IImageReaderWriter destImage, ScanlineRasterizer sclineRas, Scanline scline, VertexStore vxs, Drawing.Color[] colors, int[] path_id, int num_paths) { for (int i = 0; i < num_paths; ++i) { sclineRas.Reset(); sclineRas.AddPath(new VertexStoreSnap(vxs, path_id[i])); sclineRasToBmp.RenderWithColor(destImage, sclineRas, scline, colors[i]); } }
public static void CreateBezierVxs4(VertexStore vxs, Vector2 start, Vector2 end, Vector2 control1, Vector2 control2) { var curve = new VectorMath.BezierCurveCubic( start, end, control1, control2); vxs.AddLineTo(start.x, start.y); float eachstep = (float)1 / NSteps; float stepSum = eachstep;//start for (int i = 1; i < NSteps; ++i) { var vector2 = curve.CalculatePoint(stepSum); vxs.AddLineTo(vector2.x, vector2.y); stepSum += eachstep; } vxs.AddLineTo(end.x, end.y); }
public static void CreateBezierVxs3(VertexStore vxs, Vector2 start, Vector2 end, Vector2 control1) { var curve = new VectorMath.BezierCurveQuadric( start, end, control1); vxs.AddLineTo(start.x, start.y); float eachstep = (float)1 / NSteps; float stepSum = eachstep;//start for (int i = 1; i < NSteps; ++i) { var vector2 = curve.CalculatePoint(stepSum); vxs.AddLineTo(vector2.x, vector2.y); stepSum += eachstep; } vxs.AddLineTo(end.x, end.y); //------------------------------------------------------ //convert c3 to c4 //Vector2 c4p2, c4p3; //Curve3GetControlPoints(start, control1, end, out c4p2, out c4p3); //CreateBezierVxs4(vxs, start, end, c4p2, c4p3); }
public static VxsContext1 Borrow(out VertexStore vxs) => new VxsContext1(out vxs);
public static void SetSharedState(VertexStore vxs, bool isShared) { vxs.IsShared = isShared; }
/// <summary> /// copy data from 'another' append to this vxs,we DO NOT store 'another' vxs inside this /// </summary> /// <param name="another"></param> public void AppendVertexStore(VertexStore another) { //append data from another if (_allocated_vertices_count < _vertices_count + another._vertices_count) { //alloc a new one int new_alloc = _vertices_count + another._vertices_count; //_vertices_count = new_alloc;//new var new_coord_xy = new double[(new_alloc + 1) << 1];//*2 var new_cmds = new byte[(new_alloc + 1)]; //copy org //A.1 System.Array.Copy( _coord_xy, //src_arr 0, //src_index new_coord_xy, //dst 0, //dst index _vertices_count << 1); //len //A.2 System.Array.Copy( _cmds, //src_arr 0, //src_index new_cmds, //dst 0, //dst index _vertices_count); //len //B.1 System.Array.Copy( another._coord_xy, //src 0, //srcIndex new_coord_xy, //dst _vertices_count << 1, //dst index another._vertices_count << 1); //** //B.2 System.Array.Copy( another._cmds, //src 0, //srcIndex new_cmds, //dst _vertices_count, //dst index another._vertices_count); _coord_xy = new_coord_xy; _cmds = new_cmds; _vertices_count += another._vertices_count; _allocated_vertices_count = new_alloc; } else { System.Array.Copy( another._coord_xy, //src 0, //src index _coord_xy, //dst _vertices_count << 1, //*2 // another._vertices_count << 1); //B.2 System.Array.Copy( another._cmds, //src 0, //src index _cmds, //dst _vertices_count, //dst index another._vertices_count); _vertices_count += another._vertices_count; } }
static Shape CreateShape(VertexStore vxs, out EdgeBmpLut bmpLut) { List <EdgeSegment> flattenEdges = new List <EdgeSegment>(); Shape shape = new Shape(); //start with blank shape int i = 0; double x, y; VertexCmd cmd; Contour cnt = null; double latestMoveToX = 0; double latestMoveToY = 0; double latestX = 0; double latestY = 0; List <ContourCorner> corners = new List <ContourCorner>(); List <int> edgeOfNextContours = new List <int>(); List <int> cornerOfNextContours = new List <int>(); while ((cmd = vxs.GetVertex(i, out x, out y)) != VertexCmd.NoMore) { switch (cmd) { case VertexCmd.Close: { //close current cnt if ((latestMoveToX != latestX) || (latestMoveToY != latestY)) { //add line to close the shape if (cnt != null) { flattenEdges.Add(cnt.AddLine(latestX, latestY, latestMoveToX, latestMoveToY)); } } if (cnt != null) { //*** CreateCorners(cnt, corners); edgeOfNextContours.Add(flattenEdges.Count); cornerOfNextContours.Add(corners.Count); shape.contours.Add(cnt); //*** cnt = null; } } break; case VertexCmd.C3: { //C3 curve (Quadratic) if (cnt == null) { cnt = new Contour(); } VertexCmd cmd1 = vxs.GetVertex(i + 1, out double x1, out double y1); i++; if (cmd1 != VertexCmd.LineTo) { throw new NotSupportedException(); } //in this version, //we convert Quadratic to Cubic (https://stackoverflow.com/questions/9485788/convert-quadratic-curve-to-cubic-curve) //Control1X = StartX + ((2f/3) * (ControlX - StartX)) //Control2X = EndX + ((2f/3) * (ControlX - EndX)) //flattenEdges.Add(cnt.AddCubicSegment( // latestX, latestY, // ((2f / 3) * (x - latestX)) + latestX, ((2f / 3) * (y - latestY)) + latestY, // ((2f / 3) * (x - x1)) + x1, ((2f / 3) * (y - y1)) + y1, // x1, y1)); flattenEdges.Add(cnt.AddQuadraticSegment(latestX, latestY, x, y, x1, y1)); latestX = x1; latestY = y1; } break; case VertexCmd.C4: { //C4 curve (Cubic) if (cnt == null) { cnt = new Contour(); } VertexCmd cmd1 = vxs.GetVertex(i + 1, out double x2, out double y2); VertexCmd cmd2 = vxs.GetVertex(i + 2, out double x3, out double y3); i += 2; if (cmd1 != VertexCmd.C4 || cmd2 != VertexCmd.LineTo) { throw new NotSupportedException(); } flattenEdges.Add(cnt.AddCubicSegment(latestX, latestY, x, y, x2, y2, x3, y3)); latestX = x3; latestY = y3; } break; case VertexCmd.LineTo: { if (cnt == null) { cnt = new Contour(); } LinearSegment lineseg = cnt.AddLine(latestX, latestY, x, y); flattenEdges.Add(lineseg); latestX = x; latestY = y; } break; case VertexCmd.MoveTo: { latestX = latestMoveToX = x; latestY = latestMoveToY = y; if (cnt != null) { shape.contours.Add(cnt); cnt = null; } } break; } i++; } if (cnt != null) { shape.contours.Add(cnt); CreateCorners(cnt, corners); edgeOfNextContours.Add(flattenEdges.Count); cornerOfNextContours.Add(corners.Count); cnt = null; } GroupingOverlapContours(shape); //from a given shape we create a corner-arm for each corner bmpLut = new EdgeBmpLut(corners, flattenEdges, edgeOfNextContours, cornerOfNextContours); return(shape); }
public static void FlipY(VertexStore vxs, double y1, double y2) { int i; double x, y; int count = vxs.Count; for (i = 0; i < count; ++i) { VertexCmd flags = vxs.GetVertex(i, out x, out y); if (VertexHelper.IsVertextCommand(flags)) { vxs.ReplaceVertex(i, x, y2 - y + y1); } } }
static int ArrangeOrientations(VertexStore myvxs, int start, bool closewise) { while (start < myvxs.Count) { start = ArrangePolygonOrientation(myvxs, start, closewise); if (VertexHelper.IsEmpty(myvxs.GetCommand(start))) { ++start; break; } } return start; }
/// <summary> /// create a region from vxs (may be simple rect vxs or complex vxs) /// </summary> /// <param name="vxs"></param> public VxsRegion(VertexStore vxs) { //COPY _vxs = vxs.CreateTrim();//we don't store outside data }
protected override void OnStartDemo(SampleViewport viewport) { SvgPart svgPart = new SvgPart(SvgRenderVxKind.Path); VertexStore vxs = new VertexStore(); vxs.AddMoveTo(100, 20); vxs.AddLineTo(150, 50); vxs.AddLineTo(110, 80); vxs.AddCloseFigure(); //------------------------------------------- svgPart.SetVxsAsOriginal(vxs); svgPart.FillColor = Color.Red; SvgRenderVx svgRenderVx = new SvgRenderVx(new SvgPart[] { svgPart }); svgRenderVx.DisableBackingImage = true; var uiSprite = new UISprite(10, 10); //init size = (10,10), location=(0,0) uiSprite.LoadSvg(svgRenderVx); viewport.AddContent(uiSprite); var spriteEvListener = new GeneralEventListener(); uiSprite.AttachExternalEventListener(spriteEvListener); //box1 = new LayoutFarm.CustomWidgets.SimpleBox(50, 50); //box1.BackColor = Color.Red; //box1.SetLocation(10, 10); ////box1.dbugTag = 1; //SetupActiveBoxProperties(box1); //viewport.AddContent(box1); //-------- rectBoxController.Init(); //polygonController.Visible = false; viewport.AddContent(polygonController); //------------------------------------------- viewport.AddContent(rectBoxController); //foreach (var ui in rectBoxController.GetControllerIter()) //{ // viewport.AddContent(ui); //} spriteEvListener.MouseDown += e1 => { //mousedown on ui sprite polygonController.SetPosition((int)uiSprite.Left, (int)uiSprite.Top); polygonController.SetTargetUISprite(uiSprite); polygonController.UpdateControlPoints(svgPart); }; spriteEvListener.MouseMove += e1 => { if (e1.IsDragging) { //drag event on uisprite int left = (int)uiSprite.Left; int top = (int)uiSprite.Top; int new_left = left + e1.DiffCapturedX; int new_top = top + e1.DiffCapturedY; uiSprite.SetLocation(new_left, new_top); //----- //also update controller position polygonController.SetPosition(new_left, new_top); } }; }
public AggRenderVx(VertexStore vxs) { _vxs = vxs; }
internal static void FlattenVxs(VertexStore input, VertexStore output) { curveFlattener.MakeVxs(input, output); }
public VertexStore MakeVxs(VertexStore vxs, ICoordTransformer tx, VertexStore output) { _curve3.Reset(); _curve4.Reset(); CurvePointMode latestCurveMode = CurvePointMode.NotCurve; double x, y; VertexCmd cmd; VectorMath.Vector2 c3p2 = new VectorMath.Vector2(); VectorMath.Vector2 c4p2 = new VectorMath.Vector2(); VectorMath.Vector2 c4p3 = new VectorMath.Vector2(); double lastX = 0; double lasty = 0; double lastMoveX = 0; double lastMoveY = 0; int index = 0; bool hasTx = tx != null; while ((cmd = vxs.GetVertex(index++, out x, out y)) != VertexCmd.NoMore) { #if DEBUG if (VertexStore.dbugCheckNANs(x, y)) { } #endif //----------------- if (hasTx) { tx.Transform(ref x, ref y); } //----------------- switch (cmd) { case VertexCmd.C3: { switch (latestCurveMode) { case CurvePointMode.P2: { } break; case CurvePointMode.P3: { } break; case CurvePointMode.NotCurve: { c3p2.x = x; c3p2.y = y; } break; default: { } break; } latestCurveMode = CurvePointMode.P2; } break; case VertexCmd.C4: { //this is p3c switch (latestCurveMode) { case CurvePointMode.P2: { c3p2.x = x; c3p2.y = y; } break; case CurvePointMode.P3: { c4p3.x = x; c4p3.y = y; } break; case CurvePointMode.NotCurve: { c4p2.x = x; c4p2.y = y; } break; } latestCurveMode = CurvePointMode.P3; } break; case VertexCmd.LineTo: { switch (latestCurveMode) { case CurvePointMode.P2: { _curve3.MakeLines(output, lastX, lasty, c3p2.X, c3p2.Y, x, y); } break; case CurvePointMode.P3: { _curve4.MakeLines(output, lastX, lasty, c4p2.x, c4p2.y, c4p3.x, c4p3.y, x, y); } break; default: { output.AddVertex(x, y, cmd); } break; } //----------- latestCurveMode = CurvePointMode.NotCurve; lastX = x; lasty = y; //----------- } break; case VertexCmd.MoveTo: { //move to, and end command output.AddVertex(x, y, cmd); //----------- latestCurveMode = CurvePointMode.NotCurve; lastMoveX = lastX = x; lastMoveY = lasty = y; //----------- } break; case VertexCmd.Close: case VertexCmd.CloseAndEndFigure: { latestCurveMode = CurvePointMode.NotCurve; output.AddVertex(lastMoveX, lastMoveY, cmd); //move to begin lastX = lastMoveX; lasty = lastMoveY; } break; default: { //move to, and end command output.AddVertex(x, y, cmd); //----------- latestCurveMode = CurvePointMode.NotCurve; lastX = x; lasty = y; //----------- } break; } } return(output); }
public VertexStore MakeVxs(VertexStore vxs, VertexStore output) { return(MakeVxs(vxs, null, output)); }
public void FillPolygon(PixelFarm.Drawing.Brush brush, float[] vertex2dCoords, int npoints) { //------------- //Tesselate //2d coods lis //n point switch (this.SmoothMode) { case CanvasSmoothMode.AggSmooth: { //closed polygon //closed polygon int j = npoints / 2; //first point if (j < 2) { return; } ps.MoveTo(vertex2dCoords[0], vertex2dCoords[1]); int nn = 2; for (int i = 1; i < j; ++i) { ps.LineTo(vertex2dCoords[nn++], vertex2dCoords[nn++]); } //close ps.CloseFigure(); VertexStore vxs = ps.Vxs; sclineRas.Reset(); sclineRas.AddPath(vxs); switch (brush.BrushKind) { case Drawing.BrushKind.Solid: { var color = ((PixelFarm.Drawing.SolidBrush)brush).Color; sclineRasToGL.FillWithColor(sclineRas, sclinePack8, color); } break; default: { } break; } } break; default: { var vertextList = TessPolygon(vertex2dCoords); //----------------------------- //switch how to fill polygon switch (brush.BrushKind) { case Drawing.BrushKind.LinearGradient: case Drawing.BrushKind.Texture: { var linearGradientBrush = brush as PixelFarm.Drawing.LinearGradientBrush; GL.ClearStencil(0); //set value for clearing stencil buffer //actual clear here GL.Clear(ClearBufferMask.StencilBufferBit); //------------------- //disable rendering to color buffer GL.ColorMask(false, false, false, false); //start using stencil GL.Enable(EnableCap.StencilTest); //place a 1 where rendered GL.StencilFunc(StencilFunction.Always, 1, 1); //replace where rendered GL.StencilOp(StencilOp.Replace, StencilOp.Replace, StencilOp.Replace); //render to stencill buffer //----------------- if (this.Note1 == 1) { ////create stencil with Agg shape int j = npoints / 2; //first point if (j < 2) { return; } ps.Clear(); ps.MoveTo(vertex2dCoords[0], vertex2dCoords[1]); int nn = 2; for (int i = 1; i < j; ++i) { ps.LineTo( vertex2dCoords[nn++], vertex2dCoords[nn++]); } //close ps.CloseFigure(); VertexStore vxs = ps.Vxs; sclineRas.Reset(); sclineRas.AddPath(vxs); sclineRasToGL.FillWithColor(sclineRas, sclinePack8, PixelFarm.Drawing.Color.White); //create stencil with normal OpenGL } else { //create stencil with normal OpenGL int j = vertextList.Count; int j2 = j * 2; //VboC4V3f vbo = GenerateVboC4V3f(); ArrayList <VertexC4V2f> vrx = new ArrayList <VertexC4V2f>(); uint color_uint = PixelFarm.Drawing.Color.Black.ToABGR(); //color.ToABGR(); for (int i = 0; i < j; ++i) { var v = vertextList[i]; vrx.AddVertex(new VertexC4V2f(color_uint, (float)v.m_X, (float)v.m_Y)); } DrawVertexList(DrawMode.Triangles, vrx, vrx.Count); } //-------------------------------------- //render color //-------------------------------------- //reenable color buffer GL.ColorMask(true, true, true, true); //where a 1 was not rendered GL.StencilFunc(StencilFunction.Equal, 1, 1); //freeze stencill buffer GL.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Keep); if (this.Note1 == 1) { //------------------------------------------ //we already have valid ps from stencil step //------------------------------------------ VertexStore vxs = ps.Vxs; sclineRas.Reset(); sclineRas.AddPath(vxs); //------------------------------------------------------------------------------------- //1. we draw only alpha channel of this black color to destination color //so we use BlendFuncSeparate as follow ... GL.ColorMask(false, false, false, true); //GL.BlendFuncSeparate( // BlendingFactorSrc.DstColor, BlendingFactorDest.DstColor, //the same // BlendingFactorSrc.One, BlendingFactorDest.Zero); //use alpha chanel from source*** GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.Zero); sclineRasToGL.FillWithColor(sclineRas, sclinePack8, PixelFarm.Drawing.Color.Black); //at this point alpha component is fill in to destination //------------------------------------------------------------------------------------- //2. then fill again!, //we use alpha information from dest, //so we set blend func to ... GL.BlendFunc(BlendingFactorSrc.DstAlpha, BlendingFactorDest.OneMinusDstAlpha) GL.ColorMask(true, true, true, true); GL.BlendFunc(BlendingFactorSrc.DstAlpha, BlendingFactorDest.OneMinusDstAlpha); { //draw box of gradient color if (brush.BrushKind == Drawing.BrushKind.LinearGradient) { var colors = linearGradientBrush.GetColors(); var points = linearGradientBrush.GetStopPoints(); uint c1 = colors[0].ToABGR(); uint c2 = colors[1].ToABGR(); //create polygon for graident bg ArrayList <VertexC4V2f> vrx = GLGradientColorProvider.CalculateLinearGradientVxs( points[0].X, points[0].Y, points[1].X, points[1].Y, colors[0], colors[1]); DrawVertexList(DrawMode.Triangles, vrx, vrx.Count); } else if (brush.BrushKind == Drawing.BrushKind.Texture) { //draw texture image PixelFarm.Drawing.TextureBrush tbrush = (PixelFarm.Drawing.TextureBrush)brush; PixelFarm.Drawing.Image img = tbrush.TextureImage; GLBitmap bmpTexture = (GLBitmap)tbrush.InnerImage2; this.DrawImage(bmpTexture, 0, 0); //GLBitmapTexture bmp = GLBitmapTexture.CreateBitmapTexture(fontGlyph.glyphImage32); //this.DrawImage(bmp, 0, 0); //bmp.Dispose(); } } //restore back //3. switch to normal blending mode GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); } else { //draw box of gradient color var colors = linearGradientBrush.GetColors(); var points = linearGradientBrush.GetStopPoints(); uint c1 = colors[0].ToABGR(); uint c2 = colors[1].ToABGR(); //create polygon for graident bg var vrx = GLGradientColorProvider.CalculateLinearGradientVxs( points[0].X, points[0].Y, points[1].X, points[1].Y, colors[0], colors[1]); DrawVertexList(DrawMode.Triangles, vrx, vrx.Count); } GL.Disable(EnableCap.StencilTest); } break; default: { //unknown brush //int j = vertextList.Count; //int j2 = j * 2; //VboC4V3f vbo = GenerateVboC4V3f(); //ArrayList<VertexC4V3f> vrx = new ArrayList<VertexC4V3f>(); //uint color_int = color.ToABGR(); //for (int i = 0; i < j; ++i) //{ // var v = vertextList[i]; // vrx.AddVertex(new VertexC4V3f(color_int, (float)v.m_X, (float)v.m_Y)); //} ////------------------------------------- //GL.EnableClientState(ArrayCap.ColorArray); //GL.EnableClientState(ArrayCap.VertexArray); //int pcount = vrx.Count; //vbo.BindBuffer(); //DrawTrianglesWithVertexBuffer(vrx, pcount); //vbo.UnbindBuffer(); //GL.DisableClientState(ArrayCap.ColorArray); //GL.DisableClientState(ArrayCap.VertexArray); ////-------------------------------------- } break; } } break; } }
public PathWriter() { myvxs = new VertexStore(); }
public void ClearAndStartNewVxs(VertexStore newVxsOutput) { myvxs = newVxsOutput; Clear(); }
public void DrawEllipse(float x, float y, double rx, double ry) { ellipse.Reset(x, y, rx, ry); switch (this.SmoothMode) { case CanvasSmoothMode.AggSmooth: { VertexStore vxs = aggStroke.MakeVxs(ellipse.MakeVxs()); sclineRas.Reset(); sclineRas.AddPath(vxs); sclineRasToGL.DrawWithColor(sclineRas, sclinePack8, this.strokeColor); } break; default: { VertexStore vxs = ellipse.MakeVxs(); int n = vxs.Count; unsafe { float *coords = stackalloc float[n * 2]; int i = 0; int nn = 0; double vx, vy; var cmd = vxs.GetVertex(i, out vx, out vy); while (i < n) { switch (cmd) { case VertexCmd.MoveTo: { coords[nn++] = (float)vx; coords[nn++] = (float)vy; } break; case VertexCmd.LineTo: { coords[nn++] = (float)vx; coords[nn++] = (float)vy; } break; case VertexCmd.Stop: { } break; default: { } break; } i++; cmd = vxs.GetVertex(i, out vx, out vy); } //-------------------------------------- UnsafeDrawV2fList(DrawMode.LineLoop, coords, nn / 2); } } break; } }
//-------------------------------------------------------------------- public static void InvertPolygon(VertexStore myvxs, int start) { // Skip all non-vertices at the beginning int vcount = myvxs.Count; while (start < vcount && !VertexHelper.IsVertextCommand(myvxs.GetCommand(start))) { ++start; } // Skip all insignificant move_to while (start + 1 < vcount && VertexHelper.IsMoveTo(myvxs.GetCommand(start)) && VertexHelper.IsMoveTo(myvxs.GetCommand(start + 1))) { ++start; } // Find the last vertex int end = start + 1; while (end < vcount && !VertexHelper.IsNextPoly(myvxs.GetCommand(end))) { ++end; } InvertPolygon(myvxs, start, end); }
public void DrawArc(float fromX, float fromY, float endX, float endY, float xaxisRotationAngleDec, float rx, float ry, SvgArcSize arcSize, SvgArcSweep arcSweep) { //------------------ //SVG Elliptical arc ... //from Apache Batik //----------------- CenterFormArc centerFormArc = new CenterFormArc(); ComputeArc2(fromX, fromY, rx, ry, DegToRad(xaxisRotationAngleDec), arcSize == SvgArcSize.Large, arcSweep == SvgArcSweep.Negative, endX, endY, ref centerFormArc); arcTool.Init(centerFormArc.cx, centerFormArc.cy, rx, ry, centerFormArc.radStartAngle, (centerFormArc.radStartAngle + centerFormArc.radSweepDiff)); VertexStore vxs = new VertexStore(); bool stopLoop = false; foreach (VertexData vertexData in arcTool.GetVertexIter()) { switch (vertexData.command) { case VertexCmd.Stop: stopLoop = true; break; default: vxs.AddVertex(vertexData.x, vertexData.y, vertexData.command); //yield return vertexData; break; } //------------------------------ if (stopLoop) { break; } } double scaleRatio = 1; if (centerFormArc.scaleUp) { int vxs_count = vxs.Count; double px0, py0, px_last, py_last; vxs.GetVertex(0, out px0, out py0); vxs.GetVertex(vxs_count - 1, out px_last, out py_last); double distance1 = Math.Sqrt((px_last - px0) * (px_last - px0) + (py_last - py0) * (py_last - py0)); double distance2 = Math.Sqrt((endX - fromX) * (endX - fromX) + (endY - fromY) * (endY - fromY)); if (distance1 < distance2) { scaleRatio = distance2 / distance1; } else { } } if (xaxisRotationAngleDec != 0) { //also rotate if (centerFormArc.scaleUp) { var mat = PixelFarm.Agg.Transform.Affine.NewMatix( new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy), new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Scale, scaleRatio, scaleRatio), new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Rotate, DegToRad(xaxisRotationAngleDec)), new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy)); vxs = mat.TransformToVxs(vxs); } else { //not scalue var mat = PixelFarm.Agg.Transform.Affine.NewMatix( new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy), new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Rotate, DegToRad(xaxisRotationAngleDec)), new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy)); vxs = mat.TransformToVxs(vxs); } } else { //no rotate if (centerFormArc.scaleUp) { var mat = PixelFarm.Agg.Transform.Affine.NewMatix( new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, -centerFormArc.cx, -centerFormArc.cy), new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Scale, scaleRatio, scaleRatio), new PixelFarm.Agg.Transform.AffinePlan(PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, centerFormArc.cx, centerFormArc.cy)); vxs = mat.TransformToVxs(vxs); } } vxs = aggStroke.MakeVxs(vxs); sclineRas.Reset(); sclineRas.AddPath(vxs); sclineRasToGL.DrawWithColor(sclineRas, sclinePack8, this.strokeColor); }
public VertexStore MakeVxs(VertexStore outputVxs) { for (int i = 0; i < 8; ++i) { VertexCmd cmd; outputVxs.AddVertex(m_x[i], m_y[i], cmd = m_cmd[i]); if (cmd == VertexCmd.Stop) { break; } } return outputVxs; }
/// <summary> /// create lines from curve /// </summary> /// <param name="vxs"></param> public void MakeLines(VertexStore vxs, double x1, double y1, double cx, double cy, double x2, double y2) { BezierCurve.CreateBezierVxs3(vxs, new PixelFarm.VectorMath.Vector2(x1, y1), new PixelFarm.VectorMath.Vector2(x2, y2), new PixelFarm.VectorMath.Vector2(cx, cy)); return; if (this.m_approximation_method == Curves.CurveApproximationMethod.Inc) { //m_curve_inc.Init(x1, y1, cx, cy, x2, y2); //bool isFirst = true; //foreach (VertexData currentVertextData in m_curve_inc.GetVertexIter()) //{ // if (isFirst) // { // isFirst = false; // continue; // } // if (ShapePath.IsEmpty(currentVertextData.command)) // { // break; // } // VertexData vertexData = new VertexData( // NxCmdAndFlags.LineTo, // currentVertextData.position); // vxs.AddVertex(vertexData); //} } else { m_curve_div.Init(x1, y1, cx, cy, x2, y2); m_curve_div.MakeLines(vxs); } ////--------------------------------------------------------------------- //IEnumerator<VertexData> curveIterator = this.GetVertexIter().GetEnumerator(); //curveIterator.MoveNext(); // First call returns path_cmd_move_to //do //{ // curveIterator.MoveNext(); // VertexData currentVertextData = curveIterator.Current; // if (ShapePath.IsEmpty(currentVertextData.command)) // { // break; // } // VertexData vertexData = new VertexData( // NxCmdAndFlags.LineTo, // currentVertextData.position); // vxs.AddVertex(vertexData); //} while (!ShapePath.IsEmpty(curveIterator.Current.command)); }
//------------------------------------------------------- public VertexStoreSnap MakeVertexSnap(VertexStore vxs) { return new VertexStoreSnap(MakeVxs(vxs)); }
static void SimpleBlankLine(VertexStore outputVxs, VertexCmd cmd, double x, double y) { }
void render_gpc(Painter p) { switch (this.PolygonSet) { case PolygonExampleSet.TwoSimplePaths: { //------------------------------------ // Two simple paths // PathWriter ps1 = new PathWriter(); PathWriter ps2 = new PathWriter(); double x = m_x - Width / 2 + 100; double y = m_y - Height / 2 + 100; ps1.MoveTo(x + 140, y + 145); ps1.LineTo(x + 225, y + 44); ps1.LineTo(x + 296, y + 219); ps1.CloseFigure(); // ps1.LineTo(x + 226, y + 289); ps1.LineTo(x + 82, y + 292); // ps1.MoveTo(x + 220, y + 222); ps1.LineTo(x + 363, y + 249); ps1.LineTo(x + 265, y + 331); ps1.MoveTo(x + 242, y + 243); ps1.LineTo(x + 268, y + 309); ps1.LineTo(x + 325, y + 261); ps1.MoveTo(x + 259, y + 259); ps1.LineTo(x + 273, y + 288); ps1.LineTo(x + 298, y + 266); ps1.CloseFigure(); // ps2.MoveTo(100 + 32, 100 + 77); ps2.LineTo(100 + 473, 100 + 263); ps2.LineTo(100 + 351, 100 + 290); ps2.LineTo(100 + 354, 100 + 374); ps2.CloseFigure(); p.FillColor = ColorEx.Make(0f, 0f, 0f, 0.1f); p.Fill(ps1.MakeVertexSnap()); p.FillColor = ColorEx.Make(0f, 0.6f, 0f, 0.1f); p.Fill(ps2.MakeVertexSnap()); CreateAndRenderCombined(p, ps1.MakeVertexSnap(), ps2.MakeVertexSnap()); } break; case PolygonExampleSet.CloseStroke: { //------------------------------------ // Closed stroke // PathWriter ps1 = new PathWriter(); PathWriter ps2 = new PathWriter(); Stroke stroke = new Stroke(1); stroke.Width = 10; double x = m_x - Width / 2 + 100; double y = m_y - Height / 2 + 100; //----------------------------------------- ps1.MoveTo(x + 140, y + 145); ps1.LineTo(x + 225, y + 44); ps1.LineTo(x + 296, y + 219); ps1.CloseFigure(); ps1.LineTo(x + 226, y + 289); ps1.LineTo(x + 82, y + 292); ps1.MoveTo(x + 220 - 50, y + 222); ps1.LineTo(x + 265 - 50, y + 331); ps1.LineTo(x + 363 - 50, y + 249); ps1.CloseFigureCCW(); //----------------------------------------- ps2.MoveTo(100 + 32, 100 + 77); ps2.LineTo(100 + 473, 100 + 263); ps2.LineTo(100 + 351, 100 + 290); ps2.LineTo(100 + 354, 100 + 374); ps2.CloseFigure(); p.FillColor = ColorEx.Make(0f, 0f, 0f, 0.1f); p.Fill(ps1.MakeVertexSnap()); //graphics2D.Render(ps1.MakeVertexSnap(), ColorRGBAf.MakeColorRGBA(0f, 0f, 0f, 0.1f)); var vxs = ps2.Vxs; //graphics2D.Render(stroke.MakeVxs(vxs), ColorRGBAf.MakeColorRGBA(0f, 0.6f, 0f, 0.1f)); p.FillColor = ColorEx.Make(0f, 0.6f, 0f, 0.1f); var v1 = GetFreeVxs(); p.Fill(stroke.MakeVxs(vxs, v1)); ReleaseVxs(ref v1); CreateAndRenderCombined(p, ps1.MakeVertexSnap(), new VertexStoreSnap(vxs)); } break; case PolygonExampleSet.GBAndArrow: { //------------------------------------ // Great Britain and Arrows // PathWriter gb_poly = new PathWriter(); PathWriter arrows = new PathWriter(); PixelFarm.Agg.Sample_PolygonClipping.GreatBritanPathStorage.Make(gb_poly); make_arrows(arrows); //Affine mtx1 = Affine.NewIdentity(); //mtx1 *= Affine.NewTranslation(-1150, -1150); //mtx1 *= Affine.NewScaling(2.0); Affine mtx1 = Affine.NewMatix( AffinePlan.Translate(-1150, -1150), AffinePlan.Scale(2) ); //Affine.NewIdentity(); //mtx2 = mtx1; //mtx2 *= Affine.NewTranslation(m_x - Width / 2, m_y - Height / 2); Affine mtx2 = mtx1 * Affine.NewTranslation(m_x - Width / 2, m_y - Height / 2); //VertexSourceApplyTransform trans_gb_poly = new VertexSourceApplyTransform(gb_poly, mtx1); //VertexSourceApplyTransform trans_arrows = new VertexSourceApplyTransform(arrows, mtx2); var trans_gb_poly = new VertexStore(); mtx1.TransformToVxs(gb_poly.Vxs, trans_gb_poly); var trans_arrows = new VertexStore(); mtx2.TransformToVxs(arrows.Vxs, trans_arrows); p.FillColor = ColorEx.Make(0.5f, 0.5f, 0f, 0.1f); p.Fill(trans_gb_poly); //graphics2D.Render(trans_gb_poly, ColorRGBAf.MakeColorRGBA(0.5f, 0.5f, 0f, 0.1f)); //stroke_gb_poly.Width = 0.1; p.FillColor = ColorEx.Make(0, 0, 0); var v1 = GetFreeVxs(); p.Fill(new Stroke(0.1).MakeVxs(trans_gb_poly, v1)); ReleaseVxs(ref v1); //graphics2D.Render(new Stroke(0.1).MakeVxs(trans_gb_poly), ColorRGBAf.MakeColorRGBA(0, 0, 0)); //graphics2D.Render(trans_arrows, ColorRGBAf.MakeColorRGBA(0f, 0.5f, 0.5f, 0.1f)); p.FillColor = ColorEx.Make(0f, 0.5f, 0.5f, 0.1f); p.Fill(trans_arrows); CreateAndRenderCombined(p, new VertexStoreSnap(trans_gb_poly), new VertexStoreSnap(trans_arrows)); } break; case PolygonExampleSet.GBAndSpiral: { //------------------------------------ // Great Britain and a Spiral // spiral sp = new spiral(m_x, m_y, 10, 150, 30, 0.0); PathWriter gb_poly = new PathWriter(); PixelFarm.Agg.Sample_PolygonClipping.GreatBritanPathStorage.Make(gb_poly); Affine mtx = Affine.NewMatix( AffinePlan.Translate(-1150, -1150), AffinePlan.Scale(2)); // VertexStore s1 = GetFreeVxs(); mtx.TransformToVxs(gb_poly.Vxs, s1); p.FillColor = ColorEx.Make(0.5f, 0.5f, 0f, 0.1f); p.Fill(s1); //graphics2D.Render(s1, ColorRGBAf.MakeColorRGBA(0.5f, 0.5f, 0f, 0.1f)); //graphics2D.Render(new Stroke(0.1).MakeVxs(s1), ColorRGBA.Black); p.FillColor = Color.Black; var v1 = GetFreeVxs(); var v2 = GetFreeVxs(); var v3 = GetFreeVxs(); p.Fill(new Stroke(0.1).MakeVxs(s1, v1)); var stroke_vxs = new Stroke(15).MakeVxs(sp.MakeVxs(v2), v3); p.FillColor = ColorEx.Make(0.0f, 0.5f, 0.5f, 0.1f); // XUolorRXBAf.MakeColorRGBA(0.0f, 0.5f, 0.5f, 0.1f); p.Fill(stroke_vxs); //graphics2D.Render(stroke_vxs, ColorRGBAf.MakeColorRGBA(0.0f, 0.5f, 0.5f, 0.1f)); CreateAndRenderCombined(p, new VertexStoreSnap(s1), new VertexStoreSnap(stroke_vxs)); ReleaseVxs(ref s1); ReleaseVxs(ref v1); ReleaseVxs(ref v3); ReleaseVxs(ref v2); } break; case PolygonExampleSet.SprialAndGlyph: { //------------------------------------ // Spiral and glyph // spiral sp = new spiral(m_x, m_y, 10, 150, 30, 0.0); Stroke stroke = new Stroke(15); PathWriter glyph = new PathWriter(); glyph.MoveTo(28.47, 6.45); glyph.Curve3(21.58, 1.12, 19.82, 0.29); glyph.Curve3(17.19, -0.93, 14.21, -0.93); glyph.Curve3(9.57, -0.93, 6.57, 2.25); glyph.Curve3(3.56, 5.42, 3.56, 10.60); glyph.Curve3(3.56, 13.87, 5.03, 16.26); glyph.Curve3(7.03, 19.58, 11.99, 22.51); glyph.Curve3(16.94, 25.44, 28.47, 29.64); glyph.LineTo(28.47, 31.40); glyph.Curve3(28.47, 38.09, 26.34, 40.58); glyph.Curve3(24.22, 43.07, 20.17, 43.07); glyph.Curve3(17.09, 43.07, 15.28, 41.41); glyph.Curve3(13.43, 39.75, 13.43, 37.60); glyph.LineTo(13.53, 34.77); glyph.Curve3(13.53, 32.52, 12.38, 31.30); glyph.Curve3(11.23, 30.08, 9.38, 30.08); glyph.Curve3(7.57, 30.08, 6.42, 31.35); glyph.Curve3(5.27, 32.62, 5.27, 34.81); glyph.Curve3(5.27, 39.01, 9.57, 42.53); glyph.Curve3(13.87, 46.04, 21.63, 46.04); glyph.Curve3(27.59, 46.04, 31.40, 44.04); glyph.Curve3(34.28, 42.53, 35.64, 39.31); glyph.Curve3(36.52, 37.21, 36.52, 30.71); glyph.LineTo(36.52, 15.53); glyph.Curve3(36.52, 9.13, 36.77, 7.69); glyph.Curve3(37.01, 6.25, 37.57, 5.76); glyph.Curve3(38.13, 5.27, 38.87, 5.27); glyph.Curve3(39.65, 5.27, 40.23, 5.62); glyph.Curve3(41.26, 6.25, 44.19, 9.18); glyph.LineTo(44.19, 6.45); glyph.Curve3(38.72, -0.88, 33.74, -0.88); glyph.Curve3(31.35, -0.88, 29.93, 0.78); glyph.Curve3(28.52, 2.44, 28.47, 6.45); glyph.CloseFigure(); glyph.MoveTo(28.47, 9.62); glyph.LineTo(28.47, 26.66); glyph.Curve3(21.09, 23.73, 18.95, 22.51); glyph.Curve3(15.09, 20.36, 13.43, 18.02); glyph.Curve3(11.77, 15.67, 11.77, 12.89); glyph.Curve3(11.77, 9.38, 13.87, 7.06); glyph.Curve3(15.97, 4.74, 18.70, 4.74); glyph.Curve3(22.41, 4.74, 28.47, 9.62); glyph.CloseFigure(); //Affine mtx = Affine.NewIdentity(); //mtx *= Affine.NewScaling(4.0); //mtx *= Affine.NewTranslation(220, 200); Affine mtx = Affine.NewMatix( AffinePlan.Scale(4), AffinePlan.Translate(220, 200)); var t_glyph = new VertexStore(); mtx.TransformToVertexSnap(glyph.Vxs, t_glyph); var v1 = GetFreeVxs(); var v2 = GetFreeVxs(); var v3 = GetFreeVxs(); var sp1 = stroke.MakeVxs(sp.MakeVxs(v1), v2); var curveVxs = new VertexStore(); curveFlattener.MakeVxs(t_glyph, curveVxs); CreateAndRenderCombined(p, new VertexStoreSnap(sp1), new VertexStoreSnap(curveVxs)); p.FillColor = ColorEx.Make(0f, 0f, 0f, 0.1f); p.Fill(stroke.MakeVxs(sp1, v3)); //graphics2D.Render(stroke.MakeVxs(sp1), ColorRGBAf.MakeColorRGBA(0f, 0f, 0f, 0.1f)); p.FillColor = ColorEx.Make(0f, 0.6f, 0f, 0.1f); p.Fill(curveVxs); //graphics2D.Render(curveVxs, ColorRGBAf.MakeColorRGBA(0f, 0.6f, 0f, 0.1f)); ReleaseVxs(ref v1); ReleaseVxs(ref v2); ReleaseVxs(ref v3); } break; } }
//---------------------------------- static bool GetBoundingRect(VertexStore vxs, int[] gi, int num, out double x1, out double y1, out double x2, out double y2) { int i; double x = 0; double y = 0; bool first = true; x1 = 1; y1 = 1; x2 = 0; y2 = 0; int iterindex = 0; for (i = 0; i < num; i++) { VertexCmd flags; while ((flags = vxs.GetVertex(iterindex++, out x, out y)) != VertexCmd.NoMore) { switch (flags) { //if is vertext cmd case VertexCmd.LineTo: case VertexCmd.MoveTo: case VertexCmd.P2c: case VertexCmd.P3c: { if (first) { x1 = x; y1 = y; x2 = x; y2 = y; first = false; } else { if (x < x1) { x1 = x; } if (y < y1) { y1 = y; } if (x > x2) { x2 = x; } if (y > y2) { y2 = y; } } } break; } } } return(x1 <= x2 && y1 <= y2); }
private VertexStore(VertexStore src, in PixelFarm.CpuBlit.AffineMat tx)
public override void Draw(Painter p) { if (p is GdiPlusPainter) { DrawWithWinGdi((GdiPlusPainter)p); return; } AggPainter p2 = (AggPainter)p; AggRenderSurface aggRdsf = p2.RenderSurface; var widgetsSubImage = aggRdsf.DestImage; var scline = aggRdsf.ScanlinePacked8; int width = (int)widgetsSubImage.Width; int height = (int)widgetsSubImage.Height; //change value *** if (isMaskSliderValueChanged) { generate_alpha_mask(aggRdsf.ScanlineRasToDestBitmap, aggRdsf.ScanlinePacked8, aggRdsf.ScanlineRasterizer, width, height); this.isMaskSliderValueChanged = false; } var rasterizer = aggRdsf.ScanlineRasterizer; rasterizer.SetClipBox(0, 0, width, height); //alphaMaskImageBuffer.AttachBuffer(alphaByteArray, 0, width, height, width, 8, 1); PixelFarm.Agg.Imaging.AlphaMaskAdaptor imageAlphaMaskAdaptor = new PixelFarm.Agg.Imaging.AlphaMaskAdaptor(widgetsSubImage, alphaMask); ClipProxyImage alphaMaskClippingProxy = new ClipProxyImage(imageAlphaMaskAdaptor); ClipProxyImage clippingProxy = new ClipProxyImage(widgetsSubImage); ////Affine transform = Affine.NewIdentity(); ////transform *= Affine.NewTranslation(-lionShape.Center.x, -lionShape.Center.y); ////transform *= Affine.NewScaling(lionScale, lionScale); ////transform *= Affine.NewRotation(angle + Math.PI); ////transform *= Affine.NewSkewing(skewX / 1000.0, skewY / 1000.0); ////transform *= Affine.NewTranslation(Width / 2, Height / 2); Affine transform = Affine.NewMatix( AffinePlan.Translate(-lionShape.Center.x, -lionShape.Center.y), AffinePlan.Scale(lionScale, lionScale), AffinePlan.Rotate(angle + Math.PI), AffinePlan.Skew(skewX / 1000.0, skewY / 1000.0), AffinePlan.Translate(width / 2, height / 2)); clippingProxy.Clear(Drawing.Color.White); ScanlineRasToDestBitmapRenderer sclineRasToBmp = aggRdsf.ScanlineRasToDestBitmap; // draw a background to show how the mask is working better int rect_w = 30; var v1 = GetFreeVxs(); for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { if ((i + j) % 2 != 0) { VertexSource.RoundedRect rect = new VertexSource.RoundedRect(i * rect_w, j * rect_w, (i + 1) * rect_w, (j + 1) * rect_w, 0); rect.NormalizeRadius(); // Drawing as an outline rasterizer.AddPath(rect.MakeVxs(v1)); v1.Clear(); sclineRasToBmp.RenderWithColor(clippingProxy, rasterizer, scline, ColorEx.Make(.9f, .9f, .9f)); } } } ReleaseVxs(ref v1); ////int x, y; //// Render the lion ////VertexSourceApplyTransform trans = new VertexSourceApplyTransform(lionShape.Path, transform); ////var vxlist = new System.Collections.Generic.List<VertexData>(); ////trans.DoTransform(vxlist); var tmpVxs1 = new VertexStore(); transform.TransformToVxs(lionShape.Vxs, tmpVxs1); sclineRasToBmp.RenderSolidAllPaths(alphaMaskClippingProxy, rasterizer, scline, tmpVxs1, lionShape.Colors, lionShape.PathIndexList, lionShape.NumPaths); ///* //// Render random Bresenham lines and markers //agg::renderer_markers<amask_ren_type> m(r); //for(i = 0; i < 50; i++) //{ // m.line_color(agg::rgba8(randGenerator.Next() & 0x7F, // randGenerator.Next() & 0x7F, // randGenerator.Next() & 0x7F, // (randGenerator.Next() & 0x7F) + 0x7F)); // m.fill_color(agg::rgba8(randGenerator.Next() & 0x7F, // randGenerator.Next() & 0x7F, // randGenerator.Next() & 0x7F, // (randGenerator.Next() & 0x7F) + 0x7F)); // m.line(m.coord(randGenerator.Next() % width), m.coord(randGenerator.Next() % height), // m.coord(randGenerator.Next() % width), m.coord(randGenerator.Next() % height)); // m.marker(randGenerator.Next() % width, randGenerator.Next() % height, randGenerator.Next() % 10 + 5, // agg::marker_e(randGenerator.Next() % agg::end_of_markers)); //} //// Render random anti-aliased lines //double w = 5.0; //agg::line_profile_aa profile; //profile.width(w); //typedef agg::renderer_outline_aa<amask_ren_type> renderer_type; //renderer_type ren(r, profile); //typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type; //rasterizer_type ras(ren); //ras.round_cap(true); //for(i = 0; i < 50; i++) //{ // ren.Color = agg::rgba8(randGenerator.Next() & 0x7F, // randGenerator.Next() & 0x7F, // randGenerator.Next() & 0x7F, // //255)); // (randGenerator.Next() & 0x7F) + 0x7F); // ras.move_to_d(randGenerator.Next() % width, randGenerator.Next() % height); // ras.line_to_d(randGenerator.Next() % width, randGenerator.Next() % height); // ras.render(false); //} //// Render random circles with gradient //typedef agg::gradient_linear_color<color_type> grad_color; //typedef agg::gradient_circle grad_func; //typedef agg::span_interpolator_linear<> interpolator_type; //typedef agg::span_gradient<color_type, // interpolator_type, // grad_func, // grad_color> span_grad_type; //agg::trans_affine grm; //grad_func grf; //grad_color grc(agg::rgba8(0,0,0), agg::rgba8(0,0,0)); //agg::ellipse ell; //agg::span_allocator<color_type> sa; //interpolator_type inter(grm); //span_grad_type sg(inter, grf, grc, 0, 10); //agg::renderer_scanline_aa<amask_ren_type, // agg::span_allocator<color_type>, // span_grad_type> rg(r, sa, sg); //for(i = 0; i < 50; i++) //{ // x = randGenerator.Next() % width; // y = randGenerator.Next() % height; // double r = randGenerator.Next() % 10 + 5; // grm.reset(); // grm *= agg::trans_affine_scaling(r / 10.0); // grm *= agg::trans_affine_translation(x, y); // grm.invert(); // grc.colors(agg::rgba8(255, 255, 255, 0), // agg::rgba8(randGenerator.Next() & 0x7F, // randGenerator.Next() & 0x7F, // randGenerator.Next() & 0x7F, // 255)); // sg.color_function(grc); // ell.init(x, y, r, r, 32); // g_rasterizer.add_path(ell); // agg::render_scanlines(g_rasterizer, g_scanline, rg); //} // */ ////m_num_cb.Render(g_rasterizer, g_scanline, clippingProxy); }
internal VxsContext1(out VertexStore outputVxs) { VxsTemp.GetFreeVxs(out outputVxs); _vxs = outputVxs; }
public void ReleaseVxs(ref VertexStore vxs) { _vxsPool.Release(ref vxs); }
public static VxsContext2 Borrow(out VertexStore vxs1, out VertexStore vxs2) => new VxsContext2(out vxs1, out vxs2);
public bool TryGetCacheGlyph(ushort glyphIndex, out VertexStore vxs) { return(_currentGlyphDic.TryGetValue(glyphIndex, out vxs)); }
public PathWriter(VertexStore externalVxs) { myvxs = externalVxs; }
public void RegisterCachedGlyph(ushort glyphIndex, VertexStore vxs) { _currentGlyphDic[glyphIndex] = vxs; }
//---------------------------------------------------------------- // Arrange the orientation of a polygon, all polygons in a path, // or in all paths. After calling arrange_orientations() or // arrange_orientations_all_paths(), all the polygons will have // the same orientation, i.e. path_flags_cw or path_flags_ccw //-------------------------------------------------------------------- static int ArrangePolygonOrientation(VertexStore myvxs, int start, bool clockwise) { //if (orientation == ShapePath.FlagsAndCommand.FlagNone) return start; // Skip all non-vertices at the beginning //ShapePath.FlagsAndCommand orientFlags = clockwise ? ShapePath.FlagsAndCommand.FlagCW : ShapePath.FlagsAndCommand.FlagCCW; int vcount = myvxs.Count; while (start < vcount && !VertexHelper.IsVertextCommand(myvxs.GetCommand(start))) { ++start; } // Skip all insignificant move_to while (start + 1 < vcount && VertexHelper.IsMoveTo(myvxs.GetCommand(start)) && VertexHelper.IsMoveTo(myvxs.GetCommand(start + 1))) { ++start; } // Find the last vertex int end = start + 1; while (end < vcount && !VertexHelper.IsNextPoly(myvxs.GetCommand(end))) { ++end; } if (end - start > 2) { bool isCW; if ((isCW = IsCW(myvxs, start, end)) != clockwise) { // Invert polygon, set orientation flag, and skip all end_poly InvertPolygon(myvxs, start, end); VertexCmd flags; int myvxs_count = myvxs.Count; var orientFlags = isCW ? (int)EndVertexOrientation.CW : (int)EndVertexOrientation.CCW; while (end < myvxs_count && VertexHelper.IsEndFigure(flags = myvxs.GetCommand(end))) { myvxs.ReplaceVertex(end++, orientFlags, 0); //myvxs.ReplaceCommand(end++, flags | orientFlags);// Path.set_orientation(cmd, orientation)); } } } return end; }
public VertexStoreSnap MakeVertexSnap(VertexStore output) { return new VertexStoreSnap(this.MakeVxs(output)); }
static bool IsCW(VertexStore myvxs, int start, int end) { // Calculate signed area (double area to be exact) //--------------------- int np = end - start; double area = 0.0; int i; for (i = 0; i < np; i++) { double x1, y1, x2, y2; myvxs.GetVertexXY(start + i, out x1, out y1); myvxs.GetVertexXY(start + (i + 1) % np, out x2, out y2); area += x1 * y2 - y1 * x2; } return (area < 0.0); //return (area < 0.0) ? ShapePath.FlagsAndCommand.FlagCW : ShapePath.FlagsAndCommand.FlagCCW; }
//internal use only! public static void UnsafeDirectSetData( VertexStore vstore, int m_allocated_vertices, int m_num_vertices, double[] m_coord_xy, byte[] m_CommandAndFlags) { vstore.m_num_vertices = m_num_vertices; vstore.m_allocated_vertices = m_allocated_vertices; vstore.m_coord_xy = m_coord_xy; vstore.m_cmds = m_CommandAndFlags; }
static void InvertPolygon(VertexStore myvxs, int start, int end) { int i; VertexCmd tmp_PathAndFlags = myvxs.GetCommand(start); --end; // Make "end" inclusive // Shift all commands to one position for (i = start; i < end; i++) { myvxs.ReplaceCommand(i, myvxs.GetCommand(i + 1)); } // Assign starting command to the ending command myvxs.ReplaceCommand(end, tmp_PathAndFlags); // Reverse the polygon while (end > start) { myvxs.SwapVertices(start++, end--); } }
private VertexStore(VertexStore src) { this.m_allocated_vertices = src.m_allocated_vertices; this.m_num_vertices = src.m_num_vertices; int coord_len = src.m_coord_xy.Length; int cmds_len = src.m_cmds.Length; this.m_coord_xy = new double[coord_len]; this.m_cmds = new byte[cmds_len]; System.Array.Copy( src.m_coord_xy, 0, this.m_coord_xy, 0, coord_len); System.Array.Copy( src.m_cmds, 0, this.m_cmds, 0, cmds_len); }
public static void ArrangeOrientationsAll(VertexStore myvxs, bool closewise) { int start = 0; while (start < myvxs.Count) { start = ArrangeOrientations(myvxs, start, closewise); } }
public VertexStore TransformToVxs(VertexStoreSnap snap, VertexStore vxs) { var vsnapIter = snap.GetVertexSnapIter(); double x, y; VertexCmd cmd; do { cmd = vsnapIter.GetNextVertex(out x, out y); this.Transform(ref x, ref y); vxs.AddVertex(x, y, cmd); } while (!VertexHelper.IsEmpty(cmd)); return vxs; }
void RenderWithMiniAgg(Typeface typeface, char testChar, float sizeInPoint) { //---------------------------------------------------- var builder = new MyGlyphPathBuilder(typeface); var hintTech = (HintTechnique)cmbHintTechnique.SelectedItem; builder.UseTrueTypeInstructions = false; //reset builder.UseVerticalHinting = false; //reset switch (hintTech) { case HintTechnique.TrueTypeInstruction: builder.UseTrueTypeInstructions = true; break; case HintTechnique.TrueTypeInstruction_VerticalOnly: builder.UseTrueTypeInstructions = true; builder.UseVerticalHinting = true; break; case HintTechnique.CustomAutoFit: //custom agg autofit break; } //---------------------------------------------------- builder.Build(testChar, sizeInPoint); var vxsShapeBuilder = new GlyphPathBuilderVxs(); builder.ReadShapes(vxsShapeBuilder); VertexStore vxs = vxsShapeBuilder.GetVxs(); p.UseSubPixelRendering = chkLcdTechnique.Checked; //5. use PixelFarm's Agg to render to bitmap... //5.1 clear background p.Clear(PixelFarm.Drawing.Color.White); if (chkFillBackground.Checked) { //5.2 p.FillColor = PixelFarm.Drawing.Color.Black; //5.3 if (!chkYGridFitting.Checked) { p.Fill(vxs); } } if (chkBorder.Checked) { //5.4 // p.StrokeWidth = 3; p.StrokeColor = PixelFarm.Drawing.Color.Green; //user can specific border width here... //p.StrokeWidth = 2; //5.5 p.Draw(vxs); } float pxScale = builder.GetPixelScale(); //1. autofit var autoFit = new GlyphAutoFit(); autoFit.Hint( builder.GetOutputPoints(), builder.GetOutputContours(), pxScale); var vxsShapeBuilder2 = new GlyphPathBuilderVxs(); autoFit.ReadOutput(vxsShapeBuilder2); VertexStore vxs2 = vxsShapeBuilder2.GetVxs(); // p.FillColor = PixelFarm.Drawing.Color.Black; p.Fill(vxs2); if (chkShowTess.Checked) { #if DEBUG debugDrawTriangulatedGlyph(autoFit.FitOutput, pxScale); #endif } if (chkShowGrid.Checked) { //render grid RenderGrid(800, 600, _gridSize, p); } //6. use this util to copy image from Agg actual image to System.Drawing.Bitmap PixelFarm.Agg.Imaging.BitmapHelper.CopyToGdiPlusBitmapSameSize(destImg, winBmp); //--------------- //7. just render our bitmap g.Clear(Color.White); g.DrawImage(winBmp, new Point(30, 20)); }
public static bool GetBoundingRect(VertexStore vxs, int[] gi, int num, out RectD boundingRect) { return GetBoundingRect(vxs, gi, num, out boundingRect.Left, out boundingRect.Bottom, out boundingRect.Right, out boundingRect.Top); }
//---------------------------------------------------------- public void AddSubVertices(VertexStore anotherVxs) { int j = anotherVxs.Count; this.HasMoreThanOnePart = true; for (int i = 0; i < j; ++i) { double x, y; VertexCmd cmd = anotherVxs.GetVertex(i, out x, out y); this.AddVertex(x, y, cmd); if (cmd == VertexCmd.Stop) { break; } } }
public void MakeVxs(VertexStoreSnap vsnap, VertexStore vxs) { m_curve3.Reset(); m_curve4.Reset(); var snapIter = vsnap.GetVertexSnapIter(); CurvePointMode latestCurveMode = CurvePointMode.NotCurve; double x, y; VertexCmd cmd; VectorMath.Vector2 c3p2 = new VectorMath.Vector2(); VectorMath.Vector2 c4p2 = new VectorMath.Vector2(); VectorMath.Vector2 c4p3 = new VectorMath.Vector2(); double lastX = 0; double lasty = 0; double lastMoveX = 0; double lastMoveY = 0; do { //this vertex cmd = snapIter.GetNextVertex(out x, out y); switch (cmd) { case VertexCmd.P2c: { switch (latestCurveMode) { case CurvePointMode.P2: { } break; case CurvePointMode.P3: { } break; case CurvePointMode.NotCurve: { c3p2.x = x; c3p2.y = y; } break; default: { } break; } latestCurveMode = CurvePointMode.P2; } break; case VertexCmd.P3c: { //this is p3c switch (latestCurveMode) { case CurvePointMode.P2: { c3p2.x = x; c3p2.y = y; } break; case CurvePointMode.P3: { // vxs.AddVertex(x, y, cmd); c4p3.x = x; c4p3.y = y; //m_curve4.MakeLines(vxs, // lastX, lasty, // c3p2.X, c3p2.Y, // c4p2.x, c4p2.y, // x, y); // vxs.AddVertex(x, y, cmd); } break; case CurvePointMode.NotCurve: { c4p2.x = x; c4p2.y = y; } break; } latestCurveMode = CurvePointMode.P3; } break; case VertexCmd.LineTo: { switch (latestCurveMode) { case CurvePointMode.P2: { m_curve3.MakeLines(vxs, lastX, lasty, c3p2.X, c3p2.Y, x, y); } break; case CurvePointMode.P3: { //from curve4 // vxs.AddVertex(x, y, cmd); m_curve4.MakeLines(vxs, lastX, lasty, c4p2.x, c4p2.y, c4p3.x, c4p3.y, x, y); } break; default: { vxs.AddVertex(x, y, cmd); } break; } //----------- latestCurveMode = CurvePointMode.NotCurve; lastX = x; lasty = y; //----------- } break; case VertexCmd.MoveTo: { //move to, and end command vxs.AddVertex(x, y, cmd); //----------- latestCurveMode = CurvePointMode.NotCurve; lastMoveX = lastX = x; lastMoveY = lasty = y; //----------- } break; case VertexCmd.Close: case VertexCmd.CloseAndEndFigure: { latestCurveMode = CurvePointMode.NotCurve; vxs.AddVertex(x, y, cmd); //move to begin lastX = lastMoveX; lasty = lastMoveY; } break; default: { //move to, and end command vxs.AddVertex(x, y, cmd); //----------- latestCurveMode = CurvePointMode.NotCurve; lastX = x; lasty = y; //----------- } break; } } while (cmd != VertexCmd.NoMore); }
public static void UnsafeDirectGetData( VertexStore vstore, out int m_allocated_vertices, out int m_num_vertices, out double[] m_coord_xy, out byte[] m_CommandAndFlags) { m_num_vertices = vstore.m_num_vertices; m_allocated_vertices = vstore.m_allocated_vertices; m_coord_xy = vstore.m_coord_xy; m_CommandAndFlags = vstore.m_cmds; }
public VertexStore MakeVxs(VertexStore srcVxs, VertexStore outputVxs) { MakeVxs(new VertexStoreSnap(srcVxs), outputVxs); return(outputVxs); }
/// <summary> /// copy from src to the new one /// </summary> /// <param name="src"></param> /// <returns></returns> public static VertexStore CreateCopy(VertexStore src) { return new VertexStore(src); }
// VertexStore CombinePathsInternal( VertexStore a, VertexStore b, VxsClipperType vxsClipType, bool separateIntoSmallSubPaths, List <VertexStore> resultList) { //prepare instance //reset all used fields ClipType clipType = (ClipType)vxsClipType; CreatePolygons(a, _aPolys); CreatePolygons(b, _bPolys); _clipper.AddPaths(_aPolys, PolyType.ptSubject, true); _clipper.AddPaths(_bPolys, PolyType.ptClip, true); _clipper.Execute(clipType, _intersectedPolys); if (separateIntoSmallSubPaths) { VertexStore firstOutput = null; //in this case we expect that resultList must not be null*** foreach (List <IntPoint> polygon in _intersectedPolys) { int j = polygon.Count; //*** if (j > 0) { //first one IntPoint point = polygon[0]; using (VxsTemp.Borrow(out VertexStore v1)) using (VectorToolBox.Borrow(v1, out PathWriter pw)) { pw.MoveTo(point.X / 1000.0, point.Y / 1000.0); //next others ... if (j > 1) { for (int i = 1; i < j; ++i) { point = polygon[i]; pw.LineTo(point.X / 1000.0, point.Y / 1000.0); } } pw.CloseFigure(); VertexStore result = v1.CreateTrim(); if (firstOutput == null) { firstOutput = result; } resultList.Add(result); //copy pw.Clear(); } } } return(firstOutput); } else { using (VxsTemp.Borrow(out var v1)) using (VectorToolBox.Borrow(v1, out PathWriter pw)) { foreach (List <IntPoint> polygon in _intersectedPolys) { int j = polygon.Count; if (j > 0) { //first one IntPoint point = polygon[0]; pw.MoveTo(point.X / 1000.0, point.Y / 1000.0); //next others ... if (j > 1) { for (int i = 1; i < j; ++i) { point = polygon[i]; pw.LineTo(point.X / 1000.0, point.Y / 1000.0); } } pw.CloseFigure(); } } pw.Stop(); VertexStore output = v1.CreateTrim(); if (resultList != null) { resultList.Add(output);//also add to here } return(output); } } }
public VertexStore TransformToVxs(VertexStore src,VertexStore vxs) { VertexCmd cmd; double x, y; int count = src.Count; for (int i = 0; i < count; ++i) { cmd = src.GetVertex(i, out x, out y); this.Transform(ref x, ref y); vxs.AddVertex(x, y, cmd); } return vxs; }
/// <summary> /// we do NOT store vxs /// </summary> /// <param name="vxs"></param> /// <param name="c"></param> public void Render(VertexStore vxs, Drawing.Color c) { Render(new VertexStoreSnap(vxs), c); }
public VertexStore MakeVxs(VertexStore vxs) { //TODO: review here return VertexStoreBuilder.CreateVxs(this.GetVertexIter(), vxs); }
public VertexStoreSnap MakeVertexSnap(VertexStore vxs) { return(new VertexStoreSnap(this.MakeVxs(vxs))); }