Пример #1
0
 public StrokeGenerator()
 {
     m_stroker = new StrokeMath();
     vertexDistanceList = new VertexDistanceList();
     m_out_vertices = new VertexStore();
     m_status = StrokeMath.Status.Init;
 }
Пример #2
0
        public override bool Move(int mouseX, int mouseY)
        {
            bool result = base.Move(mouseX, mouseY);

            myvxs = null;
            return result;
        }
Пример #3
0
        public override void OnDraw(Graphics2D graphics2D)
        {
            if (myvxs == null)
            {
                var transform = Affine.NewMatix(
                        AffinePlan.Translate(-lionShape.Center.x, -lionShape.Center.y),
                        AffinePlan.Scale(spriteScale, spriteScale),
                        AffinePlan.Rotate(angle + Math.PI),
                        AffinePlan.Skew(skewX / 1000.0, skewY / 1000.0),
                        AffinePlan.Translate(Width / 2, Height / 2)
                );
                //create vertextStore again from origiinal path 
                myvxs = transform.TransformToVxs(lionShape.Path.Vxs, new VertexStore());
            }
            //---------------------------------------------------------------------------------------------
            {
                int j = lionShape.NumPaths;
                int[] pathList = lionShape.PathIndexList;
                PixelFarm.Drawing.Color[] colors = lionShape.Colors;
                //graphics2D.UseSubPixelRendering = true;

                for (int i = 0; i < j; ++i)
                {
                    graphics2D.Render(new VertexStoreSnap(myvxs, pathList[i]), colors[i]);
                }
            }
            //---------------------------------------------------------------------------------------------


        }
Пример #4
0
 public static VertexStore CreateVxs(IEnumerable<VertexData> iter, VertexStore vxs)
 {
      
     foreach (VertexData v in iter)
     {
         vxs.AddVertex(v.x, v.y, v.command);
     }
     return vxs;
 }
Пример #5
0
        public static SKPath CreateGraphicsPath(VertexStore vxs)
        {
            //render vertice in store
            int vcount = vxs.Count;
            double prevX = 0;
            double prevY = 0;
            double prevMoveToX = 0;
            double prevMoveToY = 0;
            //var brush_path = new System.Drawing.Drawing2D.GraphicsPath(FillMode.Winding);//*** winding for overlapped path
            var brushPath = new SKPath();
            //how to set widening mode 
            for (int i = 0; i < vcount; ++i)
            {
                double x, y;
                PixelFarm.Agg.VertexCmd cmd = vxs.GetVertex(i, out x, out y);
                switch (cmd)
                {
                    case PixelFarm.Agg.VertexCmd.MoveTo:
                        prevMoveToX = prevX = x;
                        prevMoveToY = prevY = y;
                        //brush_path.StartFigure();
                        brushPath.MoveTo((float)x, (float)y);
                        break;
                    case PixelFarm.Agg.VertexCmd.LineTo:
                        //brush_path.AddLine((float)prevX, (float)prevY, (float)x, (float)y);
                        brushPath.LineTo((float)x, (float)y);
                        prevX = x;
                        prevY = y;
                        break;
                    case PixelFarm.Agg.VertexCmd.CloseAndEndFigure:
                        //brush_path.AddLine((float)prevX, (float)prevY, (float)prevMoveToX, (float)prevMoveToY);
                        brushPath.LineTo((float)prevMoveToX, (float)prevMoveToY);

                        prevMoveToX = prevX = x;
                        prevMoveToY = prevY = y;
                        //brush_path.CloseFigure();
                        brushPath.Close();
                        break;
                    case PixelFarm.Agg.VertexCmd.EndFigure:
                        break;
                    case PixelFarm.Agg.VertexCmd.Stop:
                        i = vcount + 1;//exit from loop
                        break;
                    default:
                        throw new NotSupportedException();
                }
            }
            return brushPath;
        }
Пример #6
0
        /// <summary>
        /// get processed/scaled vxs
        /// </summary>
        /// <returns></returns>
        public VertexStore GetVxs(VertexStore vxs)
        {
            float scale = TypeFace.CalculateScale(SizeInPoints);// (float)(SizeInPoints * Resolution) / (pointsPerInch * TypeFaceUnitPerEm);
            var mat = PixelFarm.Agg.Transform.Affine.NewMatix(
                //scale
             new PixelFarm.Agg.Transform.AffinePlan(
                 PixelFarm.Agg.Transform.AffineMatrixCommand.Scale, scale, scale),
                //translate
             new PixelFarm.Agg.Transform.AffinePlan(
                 PixelFarm.Agg.Transform.AffineMatrixCommand.Translate, 1, 1)
                 );

           
            var v1 = mat.TransformToVxs(ps.Vxs, s_vxsPool.GetFreeVxs());
            curveFlattener.MakeVxs(v1, vxs);
            s_vxsPool.Release(ref v1);
            return vxs;
        }
        Affine BuildImageBoundsPath(
           int srcW, int srcH,
           VertexStore drawImageRectPath,
           double destX, double destY)
        {
            AffinePlan plan = new AffinePlan();
            if (destX != 0 || destY != 0)
            {
                plan = AffinePlan.Translate(destX, destY);
            }

            drawImageRectPath.Clear();
            drawImageRectPath.AddMoveTo(0, 0);
            drawImageRectPath.AddLineTo(srcW, 0);
            drawImageRectPath.AddLineTo(srcW, srcH);
            drawImageRectPath.AddLineTo(0, srcH);
            drawImageRectPath.AddCloseFigure();
            return Affine.NewMatix(plan);
        }
        Affine BuildImageBoundsPath(
            int srcW, int srcH,
            VertexStore drawImageRectPath,
            double destX, double destY,
            double hotspotOffsetX, double hotSpotOffsetY,
            double scaleX, double scaleY,
            double angleRad)
        {
            AffinePlan[] plan = new AffinePlan[4];
            int i = 0;
            if (hotspotOffsetX != 0.0f || hotSpotOffsetY != 0.0f)
            {
                plan[i] = AffinePlan.Translate(-hotspotOffsetX, -hotSpotOffsetY);
                i++;
            }

            if (scaleX != 1 || scaleY != 1)
            {
                plan[i] = AffinePlan.Scale(scaleX, scaleY);
                i++;
            }

            if (angleRad != 0)
            {
                plan[i] = AffinePlan.Rotate(angleRad);
                i++;
            }

            if (destX != 0 || destY != 0)
            {
                plan[i] = AffinePlan.Translate(destX, destY);
                i++;
            }

            drawImageRectPath.Clear();
            drawImageRectPath.AddMoveTo(0, 0);
            drawImageRectPath.AddLineTo(srcW, 0);
            drawImageRectPath.AddLineTo(srcW, srcH);
            drawImageRectPath.AddLineTo(0, srcH);
            drawImageRectPath.AddCloseFigure();
            return Affine.NewMatix(plan);
        }
Пример #9
0
 public override void PaintSeries(VertexStore vxs, Color[] colors, int[] pathIndexs, int numPath)
 {
     sclineRasToBmp.RenderSolidAllPaths(this.gx.DestImage,
         this.sclineRas,
         this.scline,
         vxs,
         colors,
         pathIndexs,
         numPath);
 }
Пример #10
0
 public override void Draw(VertexStore vxs)
 {
     var v1 = GetFreeVxs();
     gx.Render(stroke.MakeVxs(vxs, v1), this.strokeColor);
     ReleaseVxs(ref v1);
 }
Пример #11
0
 public abstract void PaintSeries(VertexStore vxs, Color[] colors, int[] pathIndexs, int numPath);
Пример #12
0
 public abstract void PaintSeries(VertexStore vxs, Color[] colors, int[] pathIndexs, int numPath);
Пример #13
0
 public override void Draw(VertexStore vxs)
 {
     VxsHelper.DrawVxsSnap(_gfx, new VertexStoreSnap(vxs), _strokeColor);
 }
        public static VertexStore TransformToVxs(this Bilinear bilinearTx, VertexStore src, VertexStore vxs)
        {
            int       count = src.Count;
            VertexCmd cmd;
            double    x, y;

            for (int i = 0; i < count; ++i)
            {
                cmd = src.GetVertex(i, out x, out y);
                bilinearTx.Transform(ref x, ref y);
                vxs.AddVertex(x, y, cmd);
            }
            return(vxs);
        }
Пример #15
0
 void ReleaseVxs(VertexStore vxs)
 {
     this.myTmpImgRectVxs = vxs;
     vxs.Clear();
 }
 public static void TransformToVertexSnap(this Affine affine, VertexStore src, VertexStore output)
 {
     affine.TransformToVxs(src, output);
 }
        /// <summary>
        /// we do NOT store vxs, return original outputVxs
        /// </summary>
        /// <param name="src"></param>
        /// <param name="outputVxs"></param>
        /// <returns></returns>
        public static VertexStore TransformToVxs(this Affine aff, VertexStoreSnap src, VertexStore outputVxs)
        {
            var       snapIter = src.GetVertexSnapIter();
            VertexCmd cmd;
            double    x, y;

            while ((cmd = snapIter.GetNextVertex(out x, out y)) != VertexCmd.NoMore)
            {
                aff.Transform(ref x, ref y);
                outputVxs.AddVertex(x, y, cmd);
            }
            return(outputVxs);
        }
        public static VertexStore TransformToVxs(this Perspective perspecitveTx, 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);
                perspecitveTx.Transform(ref x, ref y);
                vxs.AddVertex(x, y, cmd);
            }
            return(vxs);
        }
Пример #19
0
        public VertexStore MakeVxs(VertexStore sourceVxs, VertexStore vxs)
        {
            StrokeGenerator strkgen = _strokeGen;
            int             j       = sourceVxs.Count;

            strkgen.Reset();
            VertexCmd cmd;
            double    x = 0, y = 0, startX = 0, startY = 0;

            for (int i = 0; i < j; ++i)
            {
                cmd = sourceVxs.GetVertex(i, out x, out y);
                switch (cmd)
                {
                case VertexCmd.NoMore:
                    break;

                case VertexCmd.Close:
                    if (i < j)
                    {
                        //close command
                        strkgen.Close();
                        strkgen.WriteTo(vxs);
                        strkgen.Reset();
                    }
                    else
                    {
                    }
                    break;

                case VertexCmd.CloseAndEndFigure:
                    if (i < j)
                    {
                        //close command
                        strkgen.Close();
                        strkgen.WriteTo(vxs);
                        strkgen.Reset();
                    }
                    else
                    {
                    }
                    break;

                case VertexCmd.LineTo:
                case VertexCmd.P2c:    //user must flatten the curve before do stroke
                case VertexCmd.P3c:    //user must flatten the curve before do stroke

                    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.Reset();

            return(vxs);
        }
Пример #20
0
 public StrokeGenerator()
 {
     m_stroker      = new StrokeMath();
     m_out_vertices = new VertexStore();
     m_status       = Status.Init;
 }
Пример #21
0
 internal VertexSnapIter(VertexStoreSnap vsnap)
 {
     this.vxs = vsnap.GetInternalVxs();
     this.currentIterIndex = vsnap.StartAt;
 }
        public static VertexStore TransformToVxs(this Perspective perspecitveTx, VertexStoreSnap snap, VertexStore vxs)
        {
            var       vsnapIter = snap.GetVertexSnapIter();
            double    x, y;
            VertexCmd cmd;

            do
            {
                cmd = vsnapIter.GetNextVertex(out x, out y);
                perspecitveTx.Transform(ref x, ref y);
                vxs.AddVertex(x, y, cmd);
            } while (!VertexHelper.IsEmpty(cmd));
            return(vxs);
        }
Пример #23
0
 public VertexStoreSnap(VertexStore vxs, int startAt)
 {
     this.vxs = vxs;
     this.startAt = startAt;
 }
Пример #24
0
        //-------------------------------------------------------------------

        public void AddPath(VertexStore vxs)
        {
            this.AddPath(new VertexStoreSnap(vxs));
        }
Пример #25
0
 protected void Release(ref VertexStore vxs)
 {
     _vxsPool.Release(ref vxs);
 }
Пример #26
0
 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));
 }
Пример #27
0
 /// <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);
 }
Пример #28
0
        //----------------------------------
        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);
        }
Пример #29
0
 public abstract void Fill(VertexStore vxs);
Пример #30
0
 public override void CreateStroke(VertexStore orgVxs, float strokeW, VertexStore output)
 {
     _stroke.Width = strokeW;
     _stroke.MakeVxs(orgVxs, output);
 }
Пример #31
0
 public abstract void Fill(VertexStore vxs);
Пример #32
0
 void ReleaseVxs(ref VertexStore v)
 {
     VectorToolBox.ReleaseVxs(ref v);
 }
Пример #33
0
 public abstract void Draw(VertexStore vxs);
Пример #34
0
 void ReleaseVxs(ref VertexStore vxs)
 {
     _vxsPool.Release(ref vxs);
 }
Пример #35
0
 /// <summary>
 /// fill vxs, we do NOT store vxs
 /// </summary>
 /// <param name="vxs"></param>
 public override void Fill(VertexStore vxs)
 {
     sclineRas.AddPath(vxs);
     sclineRasToBmp.RenderWithColor(this.gx.DestImage, sclineRas, scline, fillColor);
 }
Пример #36
0
 /// <summary>
 /// fill vxs, we do NOT store vxs
 /// </summary>
 /// <param name="vxs"></param>
 public override void Fill(VertexStore vxs)
 {
     sclineRas.AddPath(vxs);
     sclineRasToBmp.RenderWithColor(this.gx.DestImage, sclineRas, scline, fillColor);
 }
Пример #37
0
 /// <summary>
 /// we do NOT store vxs
 /// </summary>
 /// <param name="vxs"></param>
 /// <param name="spanGen"></param>
 public void Fill(VertexStore vxs, ISpanGenerator spanGen)
 {
     this.sclineRas.AddPath(vxs);
     sclineRasToBmp.RenderWithSpan(this.gx.DestImage, sclineRas, scline, spanGen);
 }
Пример #38
0
 /// <summary>
 /// we do NOT store vxs
 /// </summary>
 /// <param name="vxs"></param>
 /// <param name="spanGen"></param>
 public void Fill(VertexStore vxs, ISpanGenerator spanGen)
 {
     this.sclineRas.AddPath(vxs);
     sclineRasToBmp.RenderWithSpan(this.gx.DestImage, sclineRas, scline, spanGen);
 }
Пример #39
0
 public VertexStoreSnap(VertexStore vxs)
 {
     this.vxs = vxs;
     this.startAt = 0;
 }
Пример #40
0
 static void RelaseVxs(ref VertexStore vxs)
 {
     s_vxsPool.Release(ref vxs);
 }
Пример #41
0
 public void Release(ref VertexStore vxs)
 {
     vxs.Clear();
     _stack.Push(vxs);
     vxs = null;
 }
Пример #42
0
 public void WriteTo(VertexStore outputVxs)
 {
     this.Rewind();
     double x = 0, y = 0;
     for (;;)
     {
         var cmd = GetNextVertex(ref x, ref y);
         outputVxs.AddVertex(x, y, cmd);
         if (cmd == VertexCmd.Stop)
         {
             break;
         }
     }
 }
Пример #43
0
        //======= 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);
        }
 static Affine BuildImageBoundsPath(int srcW, int srcH,
    VertexStore drawImageRectPath, AffinePlan[] affPlans)
 {
     drawImageRectPath.Clear();
     drawImageRectPath.AddMoveTo(0, 0);
     drawImageRectPath.AddLineTo(srcW, 0);
     drawImageRectPath.AddLineTo(srcW, srcH);
     drawImageRectPath.AddLineTo(0, srcH);
     drawImageRectPath.AddCloseFigure();
     return Affine.NewMatix(affPlans);
 }
 /// <summary>
 /// we do NOT store vxs
 /// </summary>
 /// <param name="vxs"></param>
 /// <param name="spanGen"></param>
 void Render(VertexStore vxs, ISpanGenerator spanGen)
 {
     sclineRas.AddPath(vxs);
     sclineRasToBmp.RenderWithSpan(
         destImageReaderWriter,
         sclineRas,
         sclinePack8,
         spanGen);
 }
Пример #46
0
 /// <summary>
 /// we do NOT store snap/vxs
 /// </summary>
 /// <param name="vxs"></param>
 public override void Fill(VertexStore vxs)
 {
     VxsHelper.FillVxsSnap(_skCanvas, new VertexStoreSnap(vxs), _fill);
 }
 public static VertexStoreSnap MakeVertexSnap(this Ellipse ellipse, VertexStore vxs)
 {
     return(new VertexStoreSnap(MakeVxs(ellipse, vxs)));
 }
Пример #48
0
 public abstract void Draw(VertexStore vxs);
Пример #49
0
 public override void Draw(VertexStore vxs)
 {
     VxsHelper.DrawVxsSnap(_skCanvas, new VertexStoreSnap(vxs), _stroke);
 }
Пример #50
0
 void ReleaseVxs(ref VertexStore vxs)
 {
     _vxsPool.Release(ref vxs);
 }
Пример #51
0
 public override void PaintSeries(VertexStore vxs, Color[] colors, int[] pathIndexs, int numPath)
 {
     var prevColor = FillColor;
     for (int i = 0; i < numPath; ++i)
     {
         _fill.Color = ConvToSkColor(colors[i]);
         VxsHelper.FillVxsSnap(_skCanvas, new VertexStoreSnap(vxs, pathIndexs[i]), _fill);
     }
     FillColor = prevColor;
 }
Пример #52
0
        public override void Render(IImageReaderWriter source,
                                    double destX, double destY,
                                    double angleRadians,
                                    double inScaleX, double inScaleY)
        {
            {   // exit early if the dest and source bounds don't touch.
                // TODO: <BUG> make this do rotation and scalling
                RectInt sourceBounds = source.GetBounds();
                RectInt destBounds   = this.destImageReaderWriter.GetBounds();
                sourceBounds.Offset((int)destX, (int)destY);

                if (!RectInt.DoIntersect(sourceBounds, destBounds))
                {
                    if (inScaleX != 1 || inScaleY != 1 || angleRadians != 0)
                    {
                        throw new NotImplementedException();
                    }
                    return;
                }
            }

            double scaleX = inScaleX;
            double scaleY = inScaleY;

            Affine graphicsTransform = this.CurrentTransformMatrix;

            if (!graphicsTransform.IsIdentity())
            {
                if (scaleX != 1 || scaleY != 1 || angleRadians != 0)
                {
                    throw new NotImplementedException();
                }
                graphicsTransform.Transform(ref destX, ref destY);
            }

#if false // this is an optomization that eliminates the drawing of images that have their alpha set to all 0 (happens with generated images like explosions).
            MaxAlphaFrameProperty maxAlphaFrameProperty = MaxAlphaFrameProperty::GetMaxAlphaFrameProperty(source);

            if ((maxAlphaFrameProperty.GetMaxAlpha() * color.A_Byte) / 256 <= ALPHA_CHANNEL_BITS_DIVISOR)
            {
                m_OutFinalBlitBounds.SetRect(0, 0, 0, 0);
            }
#endif
            bool isScale = (scaleX != 1 || scaleY != 1);

            bool isRotated = true;
            if (Math.Abs(angleRadians) < (0.1 * MathHelper.Tau / 360))
            {
                isRotated    = false;
                angleRadians = 0;
            }

            //bool IsMipped = false;
            //double ox, oy;
            //source.GetOriginOffset(out ox, out oy);

            bool canUseMipMaps = isScale;
            if (scaleX > 0.5 || scaleY > 0.5)
            {
                canUseMipMaps = false;
            }

            bool renderRequriesSourceSampling = isScale || isRotated || destX != (int)destX || destY != (int)destY;

            VertexStore imgBoundsPath = GetFreeVxs();
            // this is the fast drawing path
            if (renderRequriesSourceSampling)
            {
                // if the scalling is small enough the results can be improved by using mip maps
                //if(CanUseMipMaps)
                //{
                //    CMipMapFrameProperty* pMipMapFrameProperty = CMipMapFrameProperty::GetMipMapFrameProperty(source);
                //    double OldScaleX = scaleX;
                //    double OldScaleY = scaleY;
                //    const CFrameInterface* pMippedFrame = pMipMapFrameProperty.GetMipMapFrame(ref scaleX, ref scaleY);
                //    if(pMippedFrame != source)
                //    {
                //        IsMipped = true;
                //        source = pMippedFrame;
                //        sourceOriginOffsetX *= (OldScaleX / scaleX);
                //        sourceOriginOffsetY *= (OldScaleY / scaleY);
                //    }

                //    HotspotOffsetX *= (inScaleX / scaleX);
                //    HotspotOffsetY *= (inScaleY / scaleY);
                //}

                Affine destRectTransform = BuildImageBoundsPath(source, imgBoundsPath,
                                                                destX, destY, ox, oy, scaleX, scaleY, angleRadians);

                // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004]
                Affine sourceRectTransform = destRectTransform.CreateInvert();



                var interpolator = new SpanInterpolatorLinear(sourceRectTransform);

                var imgSpanGen = new ImgSpanGenRGBA_BilinearClip(source, ColorRGBA.Black, interpolator);

                Render(destRectTransform.TransformToVxs(imgBoundsPath), imgSpanGen);



                // this is some debug you can enable to visualize the dest bounding box
                //LineFloat(BoundingRect.left, BoundingRect.top, BoundingRect.right, BoundingRect.top, WHITE);
                //LineFloat(BoundingRect.right, BoundingRect.top, BoundingRect.right, BoundingRect.bottom, WHITE);
                //LineFloat(BoundingRect.right, BoundingRect.bottom, BoundingRect.left, BoundingRect.bottom, WHITE);
                //LineFloat(BoundingRect.left, BoundingRect.bottom, BoundingRect.left, BoundingRect.top, WHITE);
            }
            else // TODO: this can be even faster if we do not use an intermediat buffer
            {
                Affine destRectTransform = BuildImageBoundsPath(source, imgBoundsPath, destX, destY);

                // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004]
                Affine sourceRectTransform = destRectTransform.CreateInvert();

                var interpolator = new SpanInterpolatorLinear(sourceRectTransform);

                ImgSpanGen imgSpanGen = null;
                switch (source.BitDepth)
                {
                case 32:
                    imgSpanGen = new ImgSpanGenRGBA_NN_StepXBy1(source, interpolator);
                    break;

                case 24:
                    imgSpanGen = new ImgSpanGenRGB_NNStepXby1(source, interpolator);
                    break;

                case 8:
                    imgSpanGen = new ImgSpanGenGray_NNStepXby1(source, interpolator);
                    break;

                default:
                    throw new NotImplementedException();
                }

                Render(destRectTransform.TransformToVxs(imgBoundsPath), imgSpanGen);
                unchecked { destImageChanged++; };
            }
            ReleaseVxs(imgBoundsPath);
        }
Пример #53
0
 /// <summary>
 /// we do NOT store snap/vxs
 /// </summary>
 /// <param name="vxs"></param>
 public override void Fill(VertexStore vxs)
 {
     VxsHelper.FillVxsSnap(_gfx, new VertexStoreSnap(vxs), _fillColor);
 }
 public static VertexStore MakeVxs(this Ellipse ellipse, VertexStore vxs)
 {
     //TODO: review here
     return(VertexStoreBuilder.CreateVxs(GetVertexIter(ellipse), vxs));
 }
Пример #55
0
 public override void PaintSeries(VertexStore vxs, Color[] colors, int[] pathIndexs, int numPath)
 {
     for (int i = 0; i < numPath; ++i)
     {
         VxsHelper.FillVxsSnap(_gfx, new VertexStoreSnap(vxs, pathIndexs[i]), colors[i]);
     }
 }
Пример #56
0
        public void CreateJoin(VertexStore output,
                               Vertex2d v0,
                               Vertex2d v1,
                               Vertex2d v2,
                               double len1,
                               double len2)
        {
            double dx1 = m_width * (v1.y - v0.y) / len1;
            double dy1 = m_width * (v1.x - v0.x) / len1;
            double dx2 = m_width * (v2.y - v1.y) / len2;
            double dy2 = m_width * (v2.x - v1.x) / len2;

            output.Clear();
            double cp = AggMath.Cross(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y);

            if (cp != 0 && (cp > 0) == (m_width > 0))
            {
                // Inner join
                //---------------
                double limit = ((len1 < len2) ? len1 : len2) / m_width_abs;
                if (limit < m_inner_miter_limit)
                {
                    limit = m_inner_miter_limit;
                }

                switch (m_inner_join)
                {
                default:     // inner_bevel
                    AddVertex(output, v1.x + dx1, v1.y - dy1);
                    AddVertex(output, v1.x + dx2, v1.y - dy2);
                    break;

                case InnerJoin.Miter:
                    CreateMiter(output,
                                v0, v1, v2, dx1, dy1, dx2, dy2,
                                LineJoin.MiterRevert,
                                limit, 0);
                    break;

                case InnerJoin.Jag:
                case InnerJoin.Round:
                    cp = (dx1 - dx2) * (dx1 - dx2) + (dy1 - dy2) * (dy1 - dy2);
                    if (cp < len1 * len1 && cp < len2 * len2)
                    {
                        CreateMiter(output,
                                    v0, v1, v2, dx1, dy1, dx2, dy2,
                                    LineJoin.MiterRevert,
                                    limit, 0);
                    }
                    else
                    {
                        if (m_inner_join == InnerJoin.Jag)
                        {
                            AddVertex(output, v1.x + dx1, v1.y - dy1);
                            AddVertex(output, v1.x, v1.y);
                            AddVertex(output, v1.x + dx2, v1.y - dy2);
                        }
                        else
                        {
                            AddVertex(output, v1.x + dx1, v1.y - dy1);
                            AddVertex(output, v1.x, v1.y);
                            CreateArc(output, v1.x, v1.y, dx2, -dy2, dx1, -dy1);
                            AddVertex(output, v1.x, v1.y);
                            AddVertex(output, v1.x + dx2, v1.y - dy2);
                        }
                    }
                    break;
                }
            }
            else
            {
                // Outer join
                //---------------

                // Calculate the distance between v1 and
                // the central point of the bevel line segment
                //---------------
                double dx     = (dx1 + dx2) / 2;
                double dy     = (dy1 + dy2) / 2;
                double dbevel = Math.Sqrt(dx * dx + dy * dy);
                if (m_line_join == LineJoin.Round || m_line_join == LineJoin.Bevel)
                {
                    // This is an optimization that reduces the number of points
                    // in cases of almost collinear segments. If there's no
                    // visible difference between bevel and miter joins we'd rather
                    // use miter join because it adds only one point instead of two.
                    //
                    // Here we calculate the middle point between the bevel points
                    // and then, the distance between v1 and this middle point.
                    // At outer joins this distance always less than stroke width,
                    // because it's actually the height of an isosceles triangle of
                    // v1 and its two bevel points. If the difference between this
                    // width and this value is small (no visible bevel) we can
                    // add just one point.
                    //
                    // The constant in the expression makes the result approximately
                    // the same as in round joins and caps. You can safely comment
                    // out this entire "if".
                    //-------------------
                    if (m_approx_scale * (m_width_abs - dbevel) < m_width_eps)
                    {
                        if (AggMath.CalcIntersect(v0.x + dx1, v0.y - dy1,
                                                  v1.x + dx1, v1.y - dy1,
                                                  v1.x + dx2, v1.y - dy2,
                                                  v2.x + dx2, v2.y - dy2,
                                                  out dx, out dy))
                        {
                            AddVertex(output, dx, dy);
                        }
                        else
                        {
                            AddVertex(output, v1.x + dx1, v1.y - dy1);
                        }
                        return;
                    }
                }

                switch (m_line_join)
                {
                case LineJoin.Miter:
                case LineJoin.MiterRevert:
                case LineJoin.MiterRound:
                    CreateMiter(output,
                                v0, v1, v2, dx1, dy1, dx2, dy2,
                                m_line_join,
                                m_miter_limit,
                                dbevel);
                    break;

                case LineJoin.Round:
                    CreateArc(output, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
                    break;

                default:     // Bevel join
                    AddVertex(output, v1.x + dx1, v1.y - dy1);
                    AddVertex(output, v1.x + dx2, v1.y - dy2);
                    break;
                }
            }
        }
Пример #57
0
        //------------------------------------------------------------------------

        /// <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);
        }
Пример #58
0
 static void AddVertex(VertexStore output, double x, double y)
 {
     output.AddVertex(x, y, VertexCmd.LineTo);
 }
Пример #59
0
        void CreateMiter(VertexStore output,
                         Vertex2d v0,
                         Vertex2d v1,
                         Vertex2d v2,
                         double dx1, double dy1,
                         double dx2, double dy2,
                         LineJoin lj,
                         double mlimit,
                         double dbevel)
        {
            double xi  = v1.x;
            double yi  = v1.y;
            double di  = 1;
            double lim = m_width_abs * mlimit;
            bool   miter_limit_exceeded = true; // Assume the worst
            bool   intersection_failed  = true; // Assume the worst

            if (AggMath.CalcIntersect(v0.x + dx1, v0.y - dy1,
                                      v1.x + dx1, v1.y - dy1,
                                      v1.x + dx2, v1.y - dy2,
                                      v2.x + dx2, v2.y - dy2,
                                      out xi, out yi))
            {
                // Calculation of the intersection succeeded
                //---------------------
                di = AggMath.calc_distance(v1.x, v1.y, xi, yi);
                if (di <= lim)
                {
                    // Inside the miter limit
                    //---------------------
                    AddVertex(output, xi, yi);
                    miter_limit_exceeded = false;
                }
                intersection_failed = false;
            }
            else
            {
                // Calculation of the intersection failed, most probably
                // the three points lie one straight line.
                // First check if v0 and v2 lie on the opposite sides of vector:
                // (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular
                // to the line determined by vertices v0 and v1.
                // This condition determines whether the next line segments continues
                // the previous one or goes back.
                //----------------
                double x2 = v1.x + dx1;
                double y2 = v1.y - dy1;
                if ((AggMath.Cross(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) ==
                    (AggMath.Cross(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0))
                {
                    // This case means that the next segment continues
                    // the previous one (straight line)
                    //-----------------
                    AddVertex(output, v1.x + dx1, v1.y - dy1);
                    miter_limit_exceeded = false;
                }
            }

            if (miter_limit_exceeded)
            {
                // Miter limit exceeded
                //------------------------
                switch (lj)
                {
                case LineJoin.MiterRevert:
                    // For the compatibility with SVG, PDF, etc,
                    // we use a simple bevel join instead of
                    // "smart" bevel
                    //-------------------
                    AddVertex(output, v1.x + dx1, v1.y - dy1);
                    AddVertex(output, v1.x + dx2, v1.y - dy2);
                    break;

                case LineJoin.MiterRound:
                    CreateArc(output, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
                    break;

                default:
                    // If no miter-revert, calculate new dx1, dy1, dx2, dy2
                    //----------------
                    if (intersection_failed)
                    {
                        mlimit *= m_width_sign;
                        AddVertex(output, v1.x + dx1 + dy1 * mlimit,
                                  v1.y - dy1 + dx1 * mlimit);
                        AddVertex(output, v1.x + dx2 - dy2 * mlimit,
                                  v1.y - dy2 - dx2 * mlimit);
                    }
                    else
                    {
                        double x1 = v1.x + dx1;
                        double y1 = v1.y - dy1;
                        double x2 = v1.x + dx2;
                        double y2 = v1.y - dy2;
                        di = (lim - dbevel) / (di - dbevel);
                        AddVertex(output, x1 + (xi - x1) * di,
                                  y1 + (yi - y1) * di);
                        AddVertex(output, x2 + (xi - x2) * di,
                                  y2 + (yi - y2) * di);
                    }
                    break;
                }
            }
        }
Пример #60
0
 public VertexStore GetUnscaledVxs()
 {
     return(VertexStore.CreateCopy(ps.Vxs));
 }