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; VectorToolBox.GetFreeVxs(out var v1); 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)); } } } VectorToolBox.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(); //lionShape.ApplyTransform(transform); throw new NotImplementedException(); //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); }
void GenerateMaskWithWinGdiPlus(int w, int h) { //1. create 32 bits for mask image this.a_alphaBmp = new System.Drawing.Bitmap(w, h); //2. create graphics based on a_alphaBmp using (System.Drawing.Graphics gfxBmp = System.Drawing.Graphics.FromImage(a_alphaBmp)) { gfxBmp.Clear(System.Drawing.Color.Black); //ClipProxyImage clippingProxy = new ClipProxyImage(image); //clippingProxy.Clear(ColorRGBA.Black); VertexSource.Ellipse ellipseForMask = new PixelFarm.Agg.VertexSource.Ellipse(); System.Random randGenerator = new Random(1432); int num = (int)maskAlphaSliderValue; int lim = num - 1; for (int i = 0; i < lim; ++i) { ellipseForMask.Reset(randGenerator.Next() % w, randGenerator.Next() % h, randGenerator.Next() % 100 + 20, randGenerator.Next() % 100 + 20, 100); // set the color to draw into the alpha channel. // there is not very much reason to set the alpha as you will get the amount of // transparency based on the color you draw. (you might want some type of different edeg effect but it will be minor). //rasterizer.AddPath(ellipseForMask.MakeVxs()); //sclineRasToBmp.RenderWithColor(clippingProxy, rasterizer, sclnPack, // ColorRGBA.Make((int)((float)i / (float)num * 255), 0, 0, 255)); VectorToolBox.GetFreeVxs(out var v1); VxsHelper.FillVxsSnap(gfxBmp, ellipseForMask.MakeVertexSnap(v1), ColorEx.Make((int)((float)i / (float)num * 255), 0, 0, 255)); VectorToolBox.ReleaseVxs(ref v1); } //the last one ellipseForMask.Reset(Width / 2, Height / 2, 110, 110, 100); //fill VectorToolBox.GetFreeVxs(out var v2); VxsHelper.FillVxsSnap(gfxBmp, ellipseForMask.MakeVertexSnap(v2), ColorEx.Make(0, 0, 0, 255)); v2.Clear();// reuse later //rasterizer.AddPath(ellipseForMask.MakeVertexSnap()); //sclineRasToBmp.RenderWithColor(clippingProxy, rasterizer, sclnPack, new ColorRGBA(0, 0, 0, 255)); ellipseForMask.Reset(ellipseForMask.originX, ellipseForMask.originY, ellipseForMask.radiusX - 10, ellipseForMask.radiusY - 10, 100); //rasterizer.AddPath(ellipseForMask.MakeVertexSnap()); //sclineRasToBmp.RenderWithColor(clippingProxy, rasterizer, sclnPack, new ColorRGBA(255, 0, 0, 255)); VxsHelper.FillVxsSnap(gfxBmp, ellipseForMask.MakeVertexSnap(v2), ColorEx.Make(255, 0, 0, 255)); VectorToolBox.ReleaseVxs(ref v2); //for (i = 0; i < num; i++) //{ // if (i == num - 1) // { // ellipseForMask.Reset(Width / 2, Height / 2, 110, 110, 100); // //fill // VxsHelper.DrawVxsSnap(gfxBmp, ellipseForMask.MakeVertexSnap(), new ColorRGBA(0, 0, 0, 255)); // //rasterizer.AddPath(ellipseForMask.MakeVertexSnap()); // //sclineRasToBmp.RenderWithColor(clippingProxy, rasterizer, sclnPack, new ColorRGBA(0, 0, 0, 255)); // ellipseForMask.Reset(ellipseForMask.originX, ellipseForMask.originY, ellipseForMask.radiusX - 10, ellipseForMask.radiusY - 10, 100); // //rasterizer.AddPath(ellipseForMask.MakeVertexSnap()); // //sclineRasToBmp.RenderWithColor(clippingProxy, rasterizer, sclnPack, new ColorRGBA(255, 0, 0, 255)); // VxsHelper.DrawVxsSnap(gfxBmp, ellipseForMask.MakeVertexSnap(), new ColorRGBA(255, 0, 0, 255)); // } // else // { // ellipseForMask.Reset(randGenerator.Next() % w, // randGenerator.Next() % h, // randGenerator.Next() % 100 + 20, // randGenerator.Next() % 100 + 20, // 100); // // set the color to draw into the alpha channel. // // there is not very much reason to set the alpha as you will get the amount of // // transparency based on the color you draw. (you might want some type of different edeg effect but it will be minor). // //rasterizer.AddPath(ellipseForMask.MakeVxs()); // //sclineRasToBmp.RenderWithColor(clippingProxy, rasterizer, sclnPack, // // ColorRGBA.Make((int)((float)i / (float)num * 255), 0, 0, 255)); // VxsHelper.DrawVxsSnap(gfxBmp, ellipseForMask.MakeVertexSnap(), ColorRGBA.Make((int)((float)i / (float)num * 255), 0, 0, 255)); // } //} } }
void DrawB(Painter p) { p.Clear(PixelFarm.Drawing.Color.White); //-------------------------- p.StrokeColor = PixelFarm.Drawing.Color.Black; p.StrokeWidth = 2.0f; using (VxsTemp.Borrow(out var v1, out var v2)) using (VectorToolBox.Borrow(v1, out PathWriter writer)) { writer.MoveTo(20, 10); writer.LineTo(60, 10); writer.LineTo(20, 200); writer.CloseFigure(); //aggPainter.LineJoin = this.LineJoin; //aggPainter.LineCap = this.LineCap; // //---------------------------------------------------- //create a dash line _dashGenLineWalker.ClearMarks(); //clear previous markers //*** //you can customize what happend with the line segment _dashGenLineWalker.AddMark(10, (outputVxs, cmd, x, y) => { //solid switch (cmd) { case VertexCmd.MoveTo: outputVxs.AddMoveTo(x, y); break; case VertexCmd.LineTo: outputVxs.AddLineTo(x, y); break; } }); _dashGenLineWalker.AddMark(10, (outputVxs, cmd, x, y) => { //whitespace, do nothing }); //then generate dash by walking along v1 _dashGenLineWalker.Walk(v1, v2); //aggPainter.Draw(vxs); //test drawline int n = v2.Count; double px = 0, py = 0; for (int i = 0; i < n; ++i) { double x, y; VertexCmd cmd = v2.GetVertex(i, out x, out y); switch (cmd) { case VertexCmd.MoveTo: px = x; py = y; break; case VertexCmd.LineTo: p.DrawLine(px, py, x, y); break; } px = x; py = y; } } //aggPainter.Draw(newvxs); }
void DrawA(Painter p) { p.Clear(PixelFarm.Drawing.Color.White); //-------------------------- p.StrokeColor = PixelFarm.Drawing.Color.Black; p.StrokeWidth = 2.0f; p.FillColor = PixelFarm.Drawing.Color.Black; // using (VxsTemp.Borrow(out var vxs)) using (VectorToolBox.Borrow(vxs, out PathWriter writer)) { writer.MoveTo(30, 10); writer.LineTo(60, 10); writer.MoveTo(10, 100); writer.LineTo(10, 50); p.Draw(vxs); } //writer.MoveTo(100, 100); //writer.LineTo(20, 200); //aggPainter.LineJoin = this.LineJoin; //aggPainter.LineCap = this.LineCap; // //---------------------------------------------------- ////create a dash line //VertexStore dashOutputVxs = new VertexStore(); //LineWalker dashGenLineWalker = new LineWalker(); ////*** ////you can customize what happend with the line segment //dashGenLineWalker.AddMark(10, LineWalkDashStyle.Solid); //dashGenLineWalker.AddMark(10, LineWalkDashStyle.Blank); ////dashGenLineWalker.AddMark(2, LineWalkDashStyle.Solid); ////dashGenLineWalker.AddMark(2, LineWalkDashStyle.Blank); //dashGenLineWalker.Walk(vxs, dashOutputVxs); ////---------------------------------------------------- //aggPainter.Draw(dashOutputVxs); ////test drawline //int n = newvxs.Count; //double px = 0, py = 0; //for (int i = 0; i < n; ++i) //{ // double x, y; // VertexCmd cmd = newvxs.GetVertex(i, out x, out y); // switch (cmd) // { // case VertexCmd.MoveTo: // px = x; // py = y; // break; // case VertexCmd.LineTo: // aggPainter.Line(px, py, x, y); // break; // } // px = x; // py = y; //} }
public override void Draw(Painter p) { //specific for agg if (p is PixelFarm.CpuBlit.AggPainter) { var p2 = (PixelFarm.CpuBlit.AggPainter)p; AggRenderSurface aggsx = p2.RenderSurface; ScanlineRasterizer rasterizer = aggsx.ScanlineRasterizer; var widgetsSubImage = PixelProcessing.BitmapBlenderExtension.CreateSubBitmapBlender(aggsx.DestBitmapBlender, aggsx.GetClippingRect()); aggsx.UseSubPixelLcdEffect = false; PixelProcessing.PixelBlenderBGRA normalBlender = new PixelProcessing.PixelBlenderBGRA(); PixelProcessing.PixelBlenderBGRA gammaBlender = new PixelProcessing.PixelBlenderBGRA(); //TODO: revisit, and fix this again gammaBlender.GammaValue = this.GammaValue; gammaBlender.EnableGamma = true; var rasterGamma = new PixelProcessing.SubBitmapBlender(widgetsSubImage, gammaBlender); ClipProxyImage clippingProxyNormal = new ClipProxyImage(widgetsSubImage); ClipProxyImage clippingProxyGamma = new ClipProxyImage(rasterGamma); clippingProxyNormal.Clear(Color.White); ScanlineUnpacked8 sl = new ScanlineUnpacked8(); int size_mul = (int)this.PixelSize; CustomScanlineRasToBmp_EnlargedSubPixelRendering ren_en = new CustomScanlineRasToBmp_EnlargedSubPixelRendering(size_mul, aggsx.DestBitmap); rasterizer.Reset(); rasterizer.MoveTo(_x[0] / size_mul, _y[0] / size_mul); rasterizer.LineTo(_x[1] / size_mul, _y[1] / size_mul); rasterizer.LineTo(_x[2] / size_mul, _y[2] / size_mul); ren_en.RenderWithColor(clippingProxyGamma, rasterizer, sl, Color.Black); //---------------------------------------- DestBitmapRasterizer sclineRasToBmp = aggsx.BitmapRasterizer; aggsx.UseSubPixelLcdEffect = false; sclineRasToBmp.RenderWithColor(clippingProxyGamma, rasterizer, sl, Color.Black); rasterizer.ResetGamma(new GammaNone()); aggsx.UseSubPixelLcdEffect = false; //---------------------------------------- using (VxsTemp.Borrow(out var v1, out var v2)) using (VectorToolBox.Borrow(v1, out PathWriter ps)) { ps.Clear(); ps.MoveTo(_x[0], _y[0]); ps.LineTo(_x[1], _y[1]); ps.LineTo(_x[2], _y[2]); ps.LineTo(_x[0], _y[0]); rasterizer.AddPath(_stroke.MakeVxs(v1, v2)); } //---------------------------------------- //Stroke stroke = new Stroke(ps); //stroke.Width = 2; //rasterizer.AddPath(stroke.MakeVxs(ps.MakeVxs())); //---------------------------------------- sclineRasToBmp.RenderWithColor(clippingProxyNormal, rasterizer, sl, new Color(200, 0, 150, 160)); } }
void ReleaseVxs(ref VertexStore v) { VectorToolBox.ReleaseVxs(ref v); }
public override void Draw(Painter p) { if (UseBitmapExt) { p.RenderQuality = RenderQuality.Fast; } else { p.RenderQuality = RenderQuality.HighQuality; } int width = 800; int height = 600; //clear the image to white // draw a circle p.Clear(Drawing.Color.White); //Ellipse ellipseVxsGen = new Ellipse(0, 0, 100, 50); using (VectorToolBox.Borrow(out Ellipse ellipseVxsGen)) using (VectorToolBox.Borrow(out Stroke stroke)) { ellipseVxsGen.Set(0, 0, 100, 50); stroke.Width = 3; for (double angleDegrees = 0; angleDegrees < 180; angleDegrees += 22.5) { var mat = Affine.NewMatix( AffinePlan.Rotate(MathHelper.DegreesToRadians(angleDegrees)), AffinePlan.Translate(width / 2, 150)); using (VxsTemp.Borrow(out var v1, out var v2, out var v3)) { ellipseVxsGen.MakeVxs(mat, v2); p.FillColor = Drawing.Color.Yellow; p.Fill(v2); //------------------------------------ p.FillColor = Drawing.Color.Blue; p.Fill(stroke.MakeVxs(v2, v3)); } } } // and a little polygon using (VxsTemp.Borrow(out var v1)) using (VectorToolBox.Borrow(v1, out PathWriter littlePoly)) { littlePoly.MoveTo(50, 50); littlePoly.LineTo(150, 50); littlePoly.LineTo(200, 200); littlePoly.LineTo(50, 150); littlePoly.LineTo(50, 50); p.FillColor = Drawing.Color.Blue; p.Fill(v1); } //--- //---- //test draw img // //g.Render(littlePoly.MakeVertexSnap(), ColorRGBA.Cyan); // draw some text // draw some text //var textPrinter = new TextPrinter(); //textPrinter.CurrentActualFont = svgFontStore.LoadFont(SvgFontStore.DEFAULT_SVG_FONTNAME, 30); //new TypeFacePrinter("Printing from a printer", 30, justification: Justification.Center); //VertexStore vxs = textPrinter.CreateVxs("Printing from a printer".ToCharArray()); //var affTx = Affine.NewTranslation(width / 2, height / 4 * 3); //VertexStore s1 = affTx.TransformToVxs(vxs); //p.FillColor = Drawing.Color.Black; //p.Fill(s1); ////g.Render(s1, ColorRGBA.Black); //p.FillColor = Drawing.Color.Red; //p.Fill(StrokeHelp.MakeVxs(s1, 1)); ////g.Render(StrokeHelp.MakeVxs(s1, 1), ColorRGBA.Red); //var aff2 = Affine.NewMatix( // AffinePlan.Rotate(MathHelper.DegreesToRadians(90)), // AffinePlan.Translate(40, height / 2)); //p.FillColor = Drawing.Color.Black; //p.Fill(aff2.TransformToVertexSnap(vxs)); ////g.Render(aff2.TransformToVertexSnap(vxs), ColorRGBA.Black); }
public override void Draw(PixelFarm.Drawing.Painter p) { p.Clear(Drawing.Color.White); p.StrokeColor = Color.Black; p.StrokeWidth = 2; p.StrokeColor = Color.Green; p.Draw(_triangleVxs); if (!ShowReconstructionCurve) { return; } //draw Ci line p.StrokeColor = Color.OrangeRed; DrawLine(p, a01, a12); DrawLine(p, a12, a20); DrawLine(p, a20, a01); //find B //DrawPoint(p, a01); //DrawPoint(p, a12); //DrawPoint(p, a20); BezierControllerArmPair c1 = BezierControllerArmPair.ReconstructControllerArms(v0, v1, v2); BezierControllerArmPair c2 = BezierControllerArmPair.ReconstructControllerArms(v1, v2, v0); BezierControllerArmPair c0 = BezierControllerArmPair.ReconstructControllerArms(v2, v0, v1); c0.UniformSmoothCoefficient = SmoothCoefficientValue; c1.UniformSmoothCoefficient = SmoothCoefficientValue; c2.UniformSmoothCoefficient = SmoothCoefficientValue; //DrawPoint(p, c0 = FindB(v0, v1, v2, out c1)); //DrawPoint(p, b2 = FindB(v1, v2, v0, out c2)); //DrawPoint(p, b0 = FindB(v2, v0, v1, out c0)); p.StrokeColor = Color.Red; DrawControllerPair(p, c0); DrawControllerPair(p, c1); DrawControllerPair(p, c2); p.StrokeColor = Color.Blue; using (VxsTemp.Borrow(out var tmpVxs1, out var tmpVxs2)) using (VectorToolBox.Borrow(tmpVxs1, out PathWriter pw)) { pw.MoveTo(c0.mid.X, c0.mid.y); pw.Curve4(c0.right.x, c0.right.y, c1.left.x, c1.left.y, c1.mid.x, c1.mid.y); //1st curve pw.Curve4(c1.right.x, c1.right.y, c2.left.x, c2.left.y, c2.mid.x, c2.mid.y); //2nd curve pw.Curve4(c2.right.x, c2.right.y, c0.left.x, c0.left.y, c0.mid.x, c0.mid.y); //3rd curve _curveflattener.MakeVxs(tmpVxs1, tmpVxs2); p.Draw(tmpVxs2); } }
public override void Draw(Painter p) { Painter painter = p; if (!didInit) { didInit = true; OnInitialize(); } //----------------------------------- painter.Clear(Drawing.Color.White); //IImageReaderWriter backBuffer = ImageHelper.CreateChildImage(gx.DestImage, gx.GetClippingRect()); //ChildImage image; //if (backBuffer.BitDepth == 32) //{ // image = new ChildImage(backBuffer, new PixelBlenderBGRA()); //} //else //{ // if (backBuffer.BitDepth != 24) // { // throw new System.NotSupportedException(); // } // image = new ChildImage(backBuffer, new PixelBlenderBGR()); //} //ClipProxyImage dest = new ClipProxyImage(image); //gx.Clear(ColorRGBA.White); //gx.SetClippingRect(new RectInt(0, 0, Width, Height)); //ScanlineRasToDestBitmapRenderer sclineRasToBmp = gx.ScanlineRasToDestBitmap; if (this.PerspectiveTransformType == Sample_Perspective.PerspectiveTransformType.Bilinear) { var bound = lionShape.Bounds; Bilinear txBilinear = Bilinear.RectToQuad(bound.Left, bound.Bottom, bound.Right, bound.Top, quadPolygonControl.GetInnerCoords()); if (txBilinear.IsValid) { VectorToolBox.GetFreeVxs(out var v3); lionShape.ApplyTransform(txBilinear); lionShape.Paint(painter); RectD lionBound = lionShape.Bounds; Ellipse ell = new Ellipse((lionBound.Left + lionBound.Right) * 0.5, (lionBound.Bottom + lionBound.Top) * 0.5, (lionBound.Right - lionBound.Left) * 0.5, (lionBound.Top - lionBound.Bottom) * 0.5, 200); VectorToolBox.ReleaseVxs(ref v3); // VectorToolBox.GetFreeVxs(out var v1, out var trans_ell); txBilinear.TransformToVxs(ell.MakeVxs(v1), trans_ell); painter.FillColor = ColorEx.Make(0.5f, 0.3f, 0.0f, 0.3f); painter.Fill(trans_ell); //------------------------------------------------------------- //outline double prevStrokeWidth = painter.StrokeWidth; painter.StrokeWidth = 3; painter.StrokeColor = ColorEx.Make(0.0f, 0.3f, 0.2f, 1.0f); painter.Draw(trans_ell); painter.StrokeWidth = prevStrokeWidth; VectorToolBox.ReleaseVxs(ref v1, ref trans_ell); } } else { RectD r = lionShape.Bounds; var txPerspective = new Perspective( r.Left, r.Bottom, r.Right, r.Top, quadPolygonControl.GetInnerCoords()); if (txPerspective.IsValid) { lionShape.Paint(p, txPerspective); //transform -> paint //painter.PaintSeries(txPerspective.TransformToVxs(lionShape.Vxs, v1), // lionShape.Colors, // lionShape.PathIndexList, // lionShape.NumPaths); //-------------------------------------------------------------------------------------- //filled Ellipse //1. create original fill ellipse RectD lionBound = lionShape.Bounds; var filledEllipse = new Ellipse((lionBound.Left + lionBound.Right) * 0.5, (lionBound.Bottom + lionBound.Top) * 0.5, (lionBound.Right - lionBound.Left) * 0.5, (lionBound.Top - lionBound.Bottom) * 0.5, 200); VectorToolBox.GetFreeVxs(out var v2, out var transformedEll); txPerspective.TransformToVxs(filledEllipse.MakeVxs(v2), transformedEll); painter.FillColor = ColorEx.Make(0.5f, 0.3f, 0.0f, 0.3f); painter.Fill(transformedEll); //-------------------------------------------------------- var prevStrokeW = painter.StrokeWidth; painter.StrokeWidth = 3; painter.StrokeColor = ColorEx.Make(0.0f, 0.3f, 0.2f, 1.0f); painter.Draw(transformedEll); painter.StrokeWidth = prevStrokeW; VectorToolBox.ReleaseVxs(ref v2, ref transformedEll); } } //-------------------------- // Render the "quad" tool and controls painter.FillColor = ColorEx.Make(0f, 0.3f, 0.5f, 0.6f); VectorToolBox.GetFreeVxs(out var v4); painter.Fill(quadPolygonControl.MakeVxs(v4)); VectorToolBox.ReleaseVxs(ref v4); }