Пример #1
0
            public ClosedLoopGlyphData(VertexStorage source)
            {
                storage = new VertexStorage();

                var vertexData = source.Vertices().Where(v => v.command != ShapePath.FlagsAndCommand.FlagNone).ToArray();

                VertexData previous = default(VertexData);

                for (var i = 0; i < vertexData.Length; i++)
                {
                    var current = vertexData[i];

                    // All MoveTo operations should be preceded by ClosePolygon
                    if (i > 0 &&
                        current.IsMoveTo &&
                        ShapePath.is_vertex(previous.command))
                    {
                        storage.ClosePolygon();
                    }

                    // Add original VertexData
                    storage.Add(current.position.X, current.position.Y, current.command);

                    // Hold prior item
                    previous = current;
                }

                // Ensure closed
                storage.ClosePolygon();
            }
Пример #2
0
 public void AddVertex(double x, double y, ShapePath.FlagsAndCommand cmd)
 {
     m_status = StrokeMath.status_e.initial;
     if (ShapePath.is_move_to(cmd))
     {
         m_src_vertices.modify_last(new VertexDistance(x, y));
     }
     else
     {
         if (ShapePath.is_vertex(cmd))
         {
             m_src_vertices.add(new VertexDistance(x, y));
         }
         else
         {
             if (ShapePath.is_end_poly(cmd))
             {
                 m_closed = (ShapePath.get_close_flag(cmd) == ShapePath.FlagsAndCommand.FlagClose);
                 if (m_orientation == ShapePath.FlagsAndCommand.FlagNone)
                 {
                     m_orientation = ShapePath.get_orientation(cmd);
                 }
             }
         }
     }
 }
Пример #3
0
        public void invert_polygon(int start)
        {
            // Skip all non-vertices at the beginning
            while (start < vertices.total_vertices() &&
                   !ShapePath.is_vertex(vertices.command(start)))
            {
                ++start;
            }

            // Skip all insignificant move_to
            while (start + 1 < vertices.total_vertices() &&
                   ShapePath.is_move_to(vertices.command(start)) &&
                   ShapePath.is_move_to(vertices.command(start + 1)))
            {
                ++start;
            }

            // Find the last vertex
            int end = start + 1;

            while (end < vertices.total_vertices() &&
                   !ShapePath.is_next_poly(vertices.command(end)))
            {
                ++end;
            }

            invert_polygon(start, end);
        }
Пример #4
0
 public void end_poly(ShapePath.FlagsAndCommand flags)
 {
     if (ShapePath.is_vertex(vertexDataManager.last_command()))
     {
         vertexDataManager.AddVertex(0.0, 0.0, ShapePath.FlagsAndCommand.EndPoly | flags);
     }
 }
Пример #5
0
 public void end_poly(ShapePath.FlagsAndCommand flags)
 {
     if (ShapePath.is_vertex(vertices.last_command()))
     {
         vertices.AddVertex(0.0, 0.0, ShapePath.FlagsAndCommand.CommandEndPoly | flags);
     }
 }
Пример #6
0
 public ShapePath.FlagsAndCommand vertex(out double x, out double y)
 {
     ShapePath.FlagsAndCommand cmd = VertexSource.vertex(out x, out y);
     if (ShapePath.is_vertex(cmd))
     {
         transformToApply.transform(ref x, ref y);
     }
     return(cmd);
 }
Пример #7
0
 public void flip_y(double y1, double y2)
 {
     for (int i = 0; i < vertexDataManager.total_vertices(); i++)
     {
         ShapePath.FlagsAndCommand PathAndFlags = vertexDataManager.vertex(i, out double x, out double y);
         if (ShapePath.is_vertex(PathAndFlags))
         {
             vertexDataManager.modify_vertex(i, x, y2 - y + y1);
         }
     }
 }
Пример #8
0
 public IEnumerable <VertexData> Vertices()
 {
     foreach (VertexData vertexData in VertexSource.Vertices())
     {
         VertexData transformedVertex = vertexData;
         if (ShapePath.is_vertex(transformedVertex.command))
         {
             transformToApply.transform(ref transformedVertex.position.x, ref transformedVertex.position.y);
         }
         yield return(transformedVertex);
     }
 }
Пример #9
0
 public void rel_to_abs(ref double x, ref double y)
 {
     if (vertices.total_vertices() != 0)
     {
         double x2;
         double y2;
         if (ShapePath.is_vertex(vertices.last_vertex(out x2, out y2)))
         {
             x += x2;
             y += y2;
         }
     }
 }
Пример #10
0
        public void flip_y(double y1, double y2)
        {
            int    i;
            double x, y;

            for (i = 0; i < vertices.total_vertices(); i++)
            {
                ShapePath.FlagsAndCommand PathAndFlags = vertices.vertex(i, out x, out y);
                if (ShapePath.is_vertex(PathAndFlags))
                {
                    vertices.modify_vertex(i, x, y2 - y + y1);
                }
            }
        }
Пример #11
0
        // Flip all vertices horizontally or vertically,
        // between x1 and x2, or between y1 and y2 respectively
        //--------------------------------------------------------------------
        public void flip_x(double x1, double x2)
        {
            int    i;
            double x, y;

            for (i = 0; i < vertexDataManager.total_vertices(); i++)
            {
                ShapePath.FlagsAndCommand PathAndFlags = vertexDataManager.vertex(i, out x, out y);
                if (ShapePath.is_vertex(PathAndFlags))
                {
                    vertexDataManager.modify_vertex(i, x2 - x + x1, y);
                }
            }
        }
Пример #12
0
        //--------------------------------------------------------------------
        public void transform_all_paths(Transform.Affine trans)
        {
            int index;
            int num_ver = vertices.total_vertices();

            for (index = 0; index < num_ver; index++)
            {
                double x, y;
                if (ShapePath.is_vertex(vertices.vertex(index, out x, out y)))
                {
                    trans.transform(ref x, ref y);
                    vertices.modify_vertex(index, x, y);
                }
            }
        }
Пример #13
0
        public void translate_all_paths(double dx, double dy)
        {
            int index;
            int num_ver = vertices.total_vertices();

            for (index = 0; index < num_ver; index++)
            {
                double x, y;
                if (ShapePath.is_vertex(vertices.vertex(index, out x, out y)))
                {
                    x += dx;
                    y += dy;
                    vertices.modify_vertex(index, x, y);
                }
            }
        }
Пример #14
0
        public void join_path(PathStorage vs, int path_id)
        {
            double x, y;

            vs.rewind(path_id);
            ShapePath.FlagsAndCommand PathAndFlags = vs.vertex(out x, out y);
            if (!ShapePath.is_stop(PathAndFlags))
            {
                if (ShapePath.is_vertex(PathAndFlags))
                {
                    double x0, y0;
                    ShapePath.FlagsAndCommand PathAndFlags0 = last_vertex(out x0, out y0);
                    if (ShapePath.is_vertex(PathAndFlags0))
                    {
                        if (agg_math.calc_distance(x, y, x0, y0) > agg_math.vertex_dist_epsilon)
                        {
                            if (ShapePath.is_move_to(PathAndFlags))
                            {
                                PathAndFlags = ShapePath.FlagsAndCommand.CommandLineTo;
                            }
                            vertices.AddVertex(x, y, PathAndFlags);
                        }
                    }
                    else
                    {
                        if (ShapePath.is_stop(PathAndFlags0))
                        {
                            PathAndFlags = ShapePath.FlagsAndCommand.CommandMoveTo;
                        }
                        else
                        {
                            if (ShapePath.is_move_to(PathAndFlags))
                            {
                                PathAndFlags = ShapePath.FlagsAndCommand.CommandLineTo;
                            }
                        }
                        vertices.AddVertex(x, y, PathAndFlags);
                    }
                }
                while (!ShapePath.is_stop(PathAndFlags = vs.vertex(out x, out y)))
                {
                    vertices.AddVertex(x, y, ShapePath.is_move_to(PathAndFlags) ?
                                       ShapePath.FlagsAndCommand.CommandLineTo :
                                       PathAndFlags);
                }
            }
        }
Пример #15
0
        // 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
        //--------------------------------------------------------------------
        public int arrange_polygon_orientation(int start, ShapePath.FlagsAndCommand orientation)
        {
            if (orientation == ShapePath.FlagsAndCommand.FlagNone)
            {
                return(start);
            }

            // Skip all non-vertices at the beginning
            while (start < vertices.total_vertices() &&
                   !ShapePath.is_vertex(vertices.command(start)))
            {
                ++start;
            }

            // Skip all insignificant move_to
            while (start + 1 < vertices.total_vertices() &&
                   ShapePath.is_move_to(vertices.command(start)) &&
                   ShapePath.is_move_to(vertices.command(start + 1)))
            {
                ++start;
            }

            // Find the last vertex
            int end = start + 1;

            while (end < vertices.total_vertices() &&
                   !ShapePath.is_next_poly(vertices.command(end)))
            {
                ++end;
            }

            if (end - start > 2)
            {
                if (perceive_polygon_orientation(start, end) != orientation)
                {
                    // Invert polygon, set orientation flag, and skip all end_poly
                    invert_polygon(start, end);
                    ShapePath.FlagsAndCommand PathAndFlags;
                    while (end < vertices.total_vertices() &&
                           ShapePath.is_end_poly(PathAndFlags = vertices.command(end)))
                    {
                        vertices.modify_command(end++, PathAndFlags | orientation);                        // Path.set_orientation(cmd, orientation));
                    }
                }
            }
            return(end);
        }
Пример #16
0
        private conv_poly_counter(IVertexSource src)
        {
            m_contours = 0;
            m_points   = 0;

            foreach (VertexData vertexData in src.Vertices())
            {
                if (ShapePath.is_vertex(vertexData.command))
                {
                    ++m_points;
                }

                if (ShapePath.is_move_to(vertexData.command))
                {
                    ++m_contours;
                }
            }
        }
Пример #17
0
 public void AddVertex(double x, double y, ShapePath.FlagsAndCommand cmd)
 {
     m_status = StrokeMath.status_e.initial;
     if (ShapePath.is_move_to(cmd))
     {
         m_src_vertices.modify_last(new VertexDistance(x, y));
     }
     else
     {
         if (ShapePath.is_vertex(cmd))
         {
             m_src_vertices.add(new VertexDistance(x, y));
         }
         else
         {
             m_closed = (int)ShapePath.get_close_flag(cmd);
         }
     }
 }
Пример #18
0
        public void transform(Transform.Affine trans, int path_id)
        {
            int num_ver = vertices.total_vertices();

            for (; path_id < num_ver; path_id++)
            {
                double x, y;
                ShapePath.FlagsAndCommand PathAndFlags = vertices.vertex(path_id, out x, out y);
                if (ShapePath.is_stop(PathAndFlags))
                {
                    break;
                }
                if (ShapePath.is_vertex(PathAndFlags))
                {
                    trans.transform(ref x, ref y);
                    vertices.modify_vertex(path_id, x, y);
                }
            }
        }
Пример #19
0
        public void translate(double dx, double dy, int path_id)
        {
            int num_ver = vertices.total_vertices();

            for (; path_id < num_ver; path_id++)
            {
                double x, y;
                ShapePath.FlagsAndCommand PathAndFlags = vertices.vertex(path_id, out x, out y);
                if (ShapePath.is_stop(PathAndFlags))
                {
                    break;
                }
                if (ShapePath.is_vertex(PathAndFlags))
                {
                    x += dx;
                    y += dy;
                    vertices.modify_vertex(path_id, x, y);
                }
            }
        }
Пример #20
0
        /// <summary>
        /// <para>Draws a quadratic Bézier curve from the current point to (x,y).</para>
        /// <para>The control point is assumed to be the reflection of the control point on the previous command relative to the current point.</para>
        /// <para>(If there is no previous command or if the previous command was not a curve, assume the control point is coincident with the current point.)</para>
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void curve3(double x, double y)
        {
            double x0;
            double y0;

            if (ShapePath.is_vertex(vertices.last_vertex(out x0, out y0)))
            {
                double x_ctrl;
                double y_ctrl;
                ShapePath.FlagsAndCommand cmd = vertices.prev_vertex(out x_ctrl, out y_ctrl);
                if (ShapePath.is_curve(cmd))
                {
                    x_ctrl = x0 + x0 - x_ctrl;
                    y_ctrl = y0 + y0 - y_ctrl;
                }
                else
                {
                    x_ctrl = x0;
                    y_ctrl = y0;
                }
                curve3(x_ctrl, y_ctrl, x, y);
            }
        }
Пример #21
0
        public void curve4(double x_ctrl2, double y_ctrl2,
                           double x_to, double y_to)
        {
            double x0;
            double y0;

            if (ShapePath.is_vertex(last_vertex(out x0, out y0)))
            {
                double x_ctrl1;
                double y_ctrl1;
                ShapePath.FlagsAndCommand cmd = prev_vertex(out x_ctrl1, out y_ctrl1);
                if (ShapePath.is_curve(cmd))
                {
                    x_ctrl1 = x0 + x0 - x_ctrl1;
                    y_ctrl1 = y0 + y0 - y_ctrl1;
                }
                else
                {
                    x_ctrl1 = x0;
                    y_ctrl1 = y0;
                }
                curve4(x_ctrl1, y_ctrl1, x_ctrl2, y_ctrl2, x_to, y_to);
            }
        }
Пример #22
0
        public ShapePath.FlagsAndCommand vertex(out double x, out double y)
        {
            x = 0;
            y = 0;
            ShapePath.FlagsAndCommand command = ShapePath.FlagsAndCommand.CommandStop;
            bool done = false;

            while (!done)
            {
                switch (m_status)
                {
                case status.initial:
                    markers.remove_all();
                    m_last_cmd = VertexSource.vertex(out m_start_x, out m_start_y);
                    m_status   = status.accumulate;
                    goto case status.accumulate;

                case status.accumulate:
                    if (ShapePath.is_stop(m_last_cmd))
                    {
                        return(ShapePath.FlagsAndCommand.CommandStop);
                    }

                    generator.RemoveAll();
                    generator.AddVertex(m_start_x, m_start_y, ShapePath.FlagsAndCommand.CommandMoveTo);
                    markers.add_vertex(m_start_x, m_start_y, ShapePath.FlagsAndCommand.CommandMoveTo);

                    for (; ;)
                    {
                        command = VertexSource.vertex(out x, out y);
                        //DebugFile.Print("x=" + x.ToString() + " y=" + y.ToString() + "\n");
                        if (ShapePath.is_vertex(command))
                        {
                            m_last_cmd = command;
                            if (ShapePath.is_move_to(command))
                            {
                                m_start_x = x;
                                m_start_y = y;
                                break;
                            }
                            generator.AddVertex(x, y, command);
                            markers.add_vertex(x, y, ShapePath.FlagsAndCommand.CommandLineTo);
                        }
                        else
                        {
                            if (ShapePath.is_stop(command))
                            {
                                m_last_cmd = ShapePath.FlagsAndCommand.CommandStop;
                                break;
                            }
                            if (ShapePath.is_end_poly(command))
                            {
                                generator.AddVertex(x, y, command);
                                break;
                            }
                        }
                    }
                    generator.Rewind(0);
                    m_status = status.generate;
                    goto case status.generate;

                case status.generate:
                    command = generator.Vertex(ref x, ref y);
                    //DebugFile.Print("x=" + x.ToString() + " y=" + y.ToString() + "\n");
                    if (ShapePath.is_stop(command))
                    {
                        m_status = status.accumulate;
                        break;
                    }
                    done = true;
                    break;
                }
            }
            return(command);
        }
Пример #23
0
        private List <Vertex> TesselateLines(List <Vector2> points, Pen p)
        {
            List <ContourVertex> vecs = new List <ContourVertex>();
            List <Vertex>        ret  = new List <Vertex>();

            if (points.Count < 2)
            {
                return(ret);
            }
            var co = color(p.Color);

            MatterHackers.Agg.VertexSource.PathStorage ps = new MatterHackers.Agg.VertexSource.PathStorage();
            ps.remove_all();
            ps.MoveTo(points[0].X, points[0].Y);

            for (int i = 1; i < points.Count; i++)
            {
                ps.LineTo(points[i].X, points[i].Y);
            }
            ps.end_poly();

            MatterHackers.Agg.VertexSource.Stroke str = new MatterHackers.Agg.VertexSource.Stroke(ps, p.Width);
            switch (p.Join)
            {
            case LineJoin.Round:
                str.line_join(MatterHackers.Agg.VertexSource.LineJoin.Round);
                str.inner_join(MatterHackers.Agg.VertexSource.InnerJoin.Round);

                break;

            case LineJoin.Miter:
                str.line_join(MatterHackers.Agg.VertexSource.LineJoin.Miter);
                str.inner_join(MatterHackers.Agg.VertexSource.InnerJoin.Miter);
                str.inner_miter_limit(p.MiterLimit);
                str.miter_limit(p.MiterLimit);
                break;
            }
            switch (p.Cap)
            {
            case LineCaps.Butt:
                str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Butt);
                break;

            case LineCaps.Round:
                str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Round);
                break;

            case LineCaps.Square:
                str.line_cap(MatterHackers.Agg.VertexSource.LineCap.Square);
                break;
            }
            str.rewind(0);
            double x, y;

            LibTessDotNet.Tess t = new LibTessDotNet.Tess();

            ShapePath.FlagsAndCommand cmd;
            do
            {
                cmd = str.vertex(out x, out y);
                if (ShapePath.is_vertex(cmd))
                {
                    vecs.Add(new ContourVertex()
                    {
                        Position = new Vec3()
                        {
                            X = (float)x, Y = (float)y
                        }
                    });
                }
                if (ShapePath.is_end_poly(cmd))
                {
                    t.AddContour(vecs.ToArray());
                    vecs.Clear();
                }
            } while (!ShapePath.is_stop(cmd));

            /*
             * foreach (var v in vertices)
             * {
             * if (!ShapePath.is_close(v.command) && !ShapePath.is_stop(v.command))
             * vecs.Add(new Vector2((float)v.position.x, (float)v.position.y));
             * }*/
            if (vecs.Count != 0)
            {
                t.AddContour(vecs.ToArray());
            }
            t.Tessellate(LibTessDotNet.WindingRule.NonZero, LibTessDotNet.ElementType.Polygons, 3);
            for (var i = 0; i < t.ElementCount; i++)
            {
                for (var tri = 0; tri < 3; tri++)
                {
                    var v = t.Vertices[t.Elements[(i * 3) + tri]].Position;
                    ret.Add(new Vertex(v.X, v.Y, co));
                }
            }
            return(ret);
        }
        public ShapePath.FlagsAndCommand vertex(out double x, out double y)
        {
            x = 0;
            y = 0;
            if (text != null && text.Length > 0)
            {
                ShapePath.FlagsAndCommand curCommand = ShapePath.FlagsAndCommand.CommandStop;
                if (currentGlyph != null)
                {
                    curCommand = currentGlyph.vertex(out x, out y);
                }

                double  xAlignOffset = 0;
                Vector2 size         = GetSize();
                switch (Justification)
                {
                case Justification.Left:
                    xAlignOffset = 0;
                    break;

                case Justification.Center:
                    xAlignOffset = -size.x / 2;
                    break;

                case Justification.Right:
                    xAlignOffset = -size.x;
                    break;

                default:
                    throw new NotImplementedException();
                }

                double yAlignOffset = 0;
                switch (Baseline)
                {
                case Baseline.Text:
                    //yAlignOffset = -typeFaceStyle.DescentInPixels;
                    yAlignOffset = 0;
                    break;

                case Baseline.BoundsTop:
                    yAlignOffset = -typeFaceStyle.AscentInPixels;
                    break;

                case Baseline.BoundsCenter:
                    yAlignOffset = -typeFaceStyle.AscentInPixels / 2;
                    break;

                default:
                    throw new NotImplementedException();
                }


                while (curCommand == ShapePath.FlagsAndCommand.CommandStop &&
                       currentChar < text.Length - 1)
                {
                    if (currentChar == 0 && text[currentChar] == '\n')
                    {
                        currentOffset.x  = 0;
                        currentOffset.y -= typeFaceStyle.EmSizeInPixels;
                    }
                    else
                    {
                        if (currentChar < text.Length)
                        {
                            // pass the next char so the typeFaceStyle can do kerning if it needs to.
                            currentOffset.x += typeFaceStyle.GetAdvanceForCharacter(text[currentChar], text[currentChar + 1]);
                        }
                        else
                        {
                            currentOffset.x += typeFaceStyle.GetAdvanceForCharacter(text[currentChar]);
                        }
                    }

                    currentChar++;
                    currentGlyph = typeFaceStyle.GetGlyphForCharacter(text[currentChar]);
                    if (currentGlyph != null)
                    {
                        currentGlyph.rewind(0);
                        curCommand = currentGlyph.vertex(out x, out y);
                    }
                    else if (text[currentChar] == '\n')
                    {
                        if (currentChar + 1 < text.Length - 1 && (text[currentChar + 1] == '\n') && text[currentChar] != text[currentChar + 1])
                        {
                            currentChar++;
                        }
                        currentOffset.x  = 0;
                        currentOffset.y -= typeFaceStyle.EmSizeInPixels;
                    }
                }

                if (ShapePath.is_vertex(curCommand))
                {
                    x += currentOffset.x + xAlignOffset + Origin.x;
                    y += currentOffset.y + yAlignOffset + Origin.y;
                }

                return(curCommand);
            }

            return(ShapePath.FlagsAndCommand.CommandStop);
        }