Пример #1
0
        public static Geometry ANT_Outline_ToGeometry(ANT_Outline outline, bool flipY, Matrix4 mtx)
        {
            if (outline == null)
            {
                return(null);
            }

            ANTOutlineGeometry path = new ANTOutlineGeometry();

            double x1, y1, x2, y2, x3, y3;

            int n;         // index of contour in outline
            int first;     // index of first point in contour
            int tag;       // current point's state

            first = 0;

            ANT_Vector_Array points = outline.points;

            for (n = 0; n < outline.n_contours; n++)
            {
                int last;  // index of last point in contour

                last = outline.contours[n];

                int limit = last;

                outline_v_start.CopyFrom(points[first]);

                outline_v_last.CopyFrom(points[last]);

                outline_v_control.CopyFrom(outline_v_start);

                int point_index = first;

                ANT_Byte_Array tags_buf   = outline.tags;
                int            tags_index = first;
                tag = ANT.ANT_CURVE_TAG(tags_buf[tags_index + 0]);

                // A contour cannot start with a cubic control point!
                if (tag == ANT_CURVE_Tag.ANT_CURVE_TAG_CUBIC)
                {
                    return(null);
                }

                // check first point to determine origin
                if (tag == ANT_CURVE_Tag.ANT_CURVE_TAG_CONIC)
                {
                    // first point is conic control.  Yes, this happens.
                    if (ANT.ANT_CURVE_TAG(tags_buf[last]) == ANT_CURVE_Tag.ANT_CURVE_TAG_ON)
                    {
                        // start at last point if it is on the curve
                        outline_v_start.CopyFrom(outline_v_last);

                        limit--;
                    }
                    else
                    {
                        // if both first and last points are conic,
                        // start at their middle and record its position
                        // for closure
                        outline_v_start.x = (outline_v_start.x + outline_v_last.x) / 2;
                        outline_v_start.y = (outline_v_start.y + outline_v_last.y) / 2;

                        outline_v_last.CopyFrom(outline_v_start);
                    }

                    point_index--;
                    tags_index--;
                }

                x1 = ANT.ANT_int26p6_to_double(outline_v_start.x);
                y1 = ANT.ANT_int26p6_to_double(outline_v_start.y);

                if (flipY)
                {
                    y1 = -y1;
                }

                mtx.Transform(ref x1, ref y1);

                path.MoveTo(x1, y1);

                while (point_index < limit)
                {
                    point_index++;
                    ANT_Vector point = points[point_index];

                    tags_index++;

                    tag = ANT.ANT_CURVE_TAG(tags_buf[tags_index + 0]);
                    switch (tag)
                    {
                    case ANT_CURVE_Tag.ANT_CURVE_TAG_ON:      // emit a single line_to
                    {
                        x1 = ANT.ANT_int26p6_to_double(point.x);
                        y1 = ANT.ANT_int26p6_to_double(point.y);

                        if (flipY)
                        {
                            y1 = -y1;
                        }

                        mtx.Transform(ref x1, ref y1);

                        path.LineTo(x1, y1);

                        continue;
                    }

                    case ANT_CURVE_Tag.ANT_CURVE_TAG_CONIC:      // consume conic arcs
                    {
                        outline_v_control.x = point.x;
                        outline_v_control.y = point.y;

Do_Conic:
                        if (point_index < limit)
                        {
                            point_index++;
                            point = points[point_index];

                            tags_index++;
                            tag = ANT.ANT_CURVE_TAG(tags_buf[tags_index + 0]);

                            outline_vec.CopyFrom(point);

                            if (tag == ANT_CURVE_Tag.ANT_CURVE_TAG_ON)
                            {
                                x1 = ANT.ANT_int26p6_to_double(outline_v_control.x);
                                y1 = ANT.ANT_int26p6_to_double(outline_v_control.y);
                                x2 = ANT.ANT_int26p6_to_double(outline_vec.x);
                                y2 = ANT.ANT_int26p6_to_double(outline_vec.y);

                                if (flipY)
                                {
                                    y1 = -y1;
                                    y2 = -y2;
                                }

                                mtx.Transform(ref x1, ref y1);
                                mtx.Transform(ref x2, ref y2);
                                path.Сurve3(x1,
                                            y1,
                                            x2,
                                            y2);
                                continue;
                            }

                            if (tag != ANT_CURVE_Tag.ANT_CURVE_TAG_CONIC)
                            {
                                return(null);
                            }

                            outline_v_middle.x = (outline_v_control.x + outline_vec.x) / 2;
                            outline_v_middle.y = (outline_v_control.y + outline_vec.y) / 2;

                            x1 = ANT.ANT_int26p6_to_double(outline_v_control.x);
                            y1 = ANT.ANT_int26p6_to_double(outline_v_control.y);
                            x2 = ANT.ANT_int26p6_to_double(outline_v_middle.x);
                            y2 = ANT.ANT_int26p6_to_double(outline_v_middle.y);

                            if (flipY)
                            {
                                y1 = -y1;
                                y2 = -y2;
                            }

                            mtx.Transform(ref x1, ref y1);
                            mtx.Transform(ref x2, ref y2);

                            path.Сurve3(x1,
                                        y1,
                                        x2,
                                        y2);

                            outline_v_control.CopyFrom(outline_vec);

                            goto Do_Conic;
                        }

                        x1 = ANT.ANT_int26p6_to_double(outline_v_control.x);
                        y1 = ANT.ANT_int26p6_to_double(outline_v_control.y);
                        x2 = ANT.ANT_int26p6_to_double(outline_v_start.x);
                        y2 = ANT.ANT_int26p6_to_double(outline_v_start.y);

                        if (flipY)
                        {
                            y1 = -y1;
                            y2 = -y2;
                        }

                        mtx.Transform(ref x1, ref y1);
                        mtx.Transform(ref x2, ref y2);

                        path.Сurve3(x1,
                                    y1,
                                    x2,
                                    y2);

                        goto Close;
                    }

                    default:
                    {
                        if (point_index + 1 > limit ||
                            ANT.ANT_CURVE_TAG(tags_buf[tags_index + 1]) != ANT_CURVE_Tag.ANT_CURVE_TAG_CUBIC)
                        {
                            return(null);
                        }

                        outline_vec1.x = points[point_index + 0].x;
                        outline_vec1.y = points[point_index + 0].y;
                        outline_vec2.x = points[point_index + 1].x;
                        outline_vec2.y = points[point_index + 1].y;

                        point_index += 2;
                        {
                            point = points[point_index];
                        }

                        tags_index += 2;

                        if (point_index <= limit)
                        {
                            outline_vec.CopyFrom(point);

                            x1 = ANT.ANT_int26p6_to_double(outline_vec1.x);
                            y1 = ANT.ANT_int26p6_to_double(outline_vec1.y);
                            x2 = ANT.ANT_int26p6_to_double(outline_vec2.x);
                            y2 = ANT.ANT_int26p6_to_double(outline_vec2.y);
                            x3 = ANT.ANT_int26p6_to_double(outline_vec.x);
                            y3 = ANT.ANT_int26p6_to_double(outline_vec.y);

                            if (flipY)
                            {
                                y1 = -y1;
                                y2 = -y2;
                                y3 = -y3;
                            }

                            mtx.Transform(ref x1, ref y1);
                            mtx.Transform(ref x2, ref y2);
                            mtx.Transform(ref x3, ref y3);

                            path.Сurve4(x1,
                                        y1,
                                        x2,
                                        y2,
                                        x3,
                                        y3);

                            continue;
                        }

                        x1 = ANT.ANT_int26p6_to_double(outline_vec1.x);
                        y1 = ANT.ANT_int26p6_to_double(outline_vec1.y);
                        x2 = ANT.ANT_int26p6_to_double(outline_vec2.x);
                        y2 = ANT.ANT_int26p6_to_double(outline_vec2.y);
                        x3 = ANT.ANT_int26p6_to_double(outline_v_start.x);
                        y3 = ANT.ANT_int26p6_to_double(outline_v_start.y);

                        if (flipY)
                        {
                            y1 = -y1;
                            y2 = -y2;
                            y3 = -y3;
                        }

                        mtx.Transform(ref x1, ref y1);
                        mtx.Transform(ref x2, ref y2);
                        mtx.Transform(ref x3, ref y3);

                        path.Сurve4(x1,
                                    y1,
                                    x2,
                                    y2,
                                    x3,
                                    y3);

                        goto Close;
                    }
                    }
                }

                path.ClosePolygon();

Close:
                first = last + 1;
            }

            return(path);
        }