示例#1
0
 public static void GetFreePathWriter(out PixelFarm.Agg.VertexSource.PathWriter p)
 {
     if (s_pathWriters.Count > 0)
     {
         p = s_pathWriters.Pop();
     }
     else
     {
         p = new Agg.VertexSource.PathWriter();
     }
 }
        unsafe internal static void BuildGlyphOutline(NativeFontGlyph fontGlyph)
        {
            FT_Outline outline = (*(FT_Outline *)fontGlyph.nativeOutlinePtr);
            //outline version
            //------------------------------
            int npoints = outline.n_points;

            int startContour     = 0;
            int cpoint_index     = 0;
            int todoContourCount = outline.n_contours;

            PixelFarm.Agg.VertexSource.PathWriter ps = new Agg.VertexSource.PathWriter();
            fontGlyph.originalVxs = ps.Vxs;
            int controlPointCount = 0;

            while (todoContourCount > 0)
            {
                int    nextContour        = outline.contours[startContour] + 1;
                bool   isFirstPoint       = true;
                FtVec2 secondControlPoint = new FtVec2();
                FtVec2 thirdControlPoint  = new FtVec2();
                bool   justFromCurveMode  = false;
                //FT_Vector vpoint = new FT_Vector();
                for (; cpoint_index < nextContour; ++cpoint_index)
                {
                    FT_Vector vpoint      = outline.points[cpoint_index];
                    byte      vtag        = outline.tags[cpoint_index];
                    bool      has_dropout = (((vtag >> 2) & 0x1) != 0);
                    int       dropoutMode = vtag >> 3;

                    // Console.WriteLine(vpoint.ToString() + " " + vtag);

                    if ((vtag & 0x1) != 0)
                    {
                        //on curve
                        if (justFromCurveMode)
                        {
                            switch (controlPointCount)
                            {
                            case 1:
                            {
                                ps.Curve3(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                          vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                            }
                            break;

                            case 2:
                            {
                                ps.Curve4(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                          thirdControlPoint.x / FT_RESIZE, thirdControlPoint.y / FT_RESIZE,
                                          vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                            }
                            break;

                            default:
                            {
                                throw new NotSupportedException();
                            }
                            }
                            controlPointCount = 0;
                            justFromCurveMode = false;
                        }
                        else
                        {
                            if (isFirstPoint)
                            {
                                isFirstPoint = false;
                                ps.MoveTo(vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                            }
                            else
                            {
                                ps.LineTo(vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                            }

                            if (has_dropout)
                            {
                                //printf("[%d] on,dropoutMode=%d: %d,y:%d \n", mm, dropoutMode, vpoint.x, vpoint.y);
                            }
                            else
                            {
                                //printf("[%d] on,x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                            }
                        }
                    }
                    else
                    {
                        switch (controlPointCount)
                        {
                        case 0:
                        {           //bit 1 set=> off curve, this is a control point
                                    //if this is a 2nd order or 3rd order control point
                            if (((vtag >> 1) & 0x1) != 0)
                            {
                                //printf("[%d] bzc3rd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                thirdControlPoint = new FtVec2(vpoint);
                            }
                            else
                            {
                                //printf("[%d] bzc2nd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                secondControlPoint = new FtVec2(vpoint);
                            }
                        }
                        break;

                        case 1:
                        {
                            if (((vtag >> 1) & 0x1) != 0)
                            {
                                //printf("[%d] bzc3rd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                thirdControlPoint = new FtVec2(vpoint);
                            }
                            else
                            {
                                //we already have prev second control point
                                //so auto calculate line to
                                //between 2 point
                                FtVec2 mid = GetMidPoint(secondControlPoint, vpoint);
                                //----------
                                //generate curve3
                                ps.Curve3(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                          mid.x / FT_RESIZE, mid.y / FT_RESIZE);
                                //------------------------
                                controlPointCount--;
                                //------------------------
                                //printf("[%d] bzc2nd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                secondControlPoint = new FtVec2(vpoint);
                            }
                        }
                        break;

                        default:
                        {
                            throw new NotSupportedException();
                        }
                        break;
                        }

                        controlPointCount++;
                        justFromCurveMode = true;
                    }
                }
                //--------
                //close figure
                //if in curve mode
                if (justFromCurveMode)
                {
                    switch (controlPointCount)
                    {
                    case 0: break;

                    case 1:
                    {
                        ps.Curve3(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                  ps.LastMoveX, ps.LastMoveY);
                    }
                    break;

                    case 2:
                    {
                        ps.Curve4(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                  thirdControlPoint.x / FT_RESIZE, thirdControlPoint.y / FT_RESIZE,
                                  ps.LastMoveX, ps.LastMoveY);
                    }
                    break;

                    default:
                    { throw new NotSupportedException(); }
                    }
                    justFromCurveMode = false;
                    controlPointCount = 0;
                }
                ps.CloseFigure();
                //--------
                startContour++;
                todoContourCount--;
            }
        }
        unsafe internal static void BuildGlyphOutline(FontGlyph fontGlyph)
        {
            FT_Outline outline = (*(FT_Outline*)fontGlyph.glyphMatrix.outline);
            //outline version
            //------------------------------
            int npoints = outline.n_points;

            int startContour = 0;
            int cpoint_index = 0;
            int todoContourCount = outline.n_contours;
            PixelFarm.Agg.VertexSource.PathWriter ps = new Agg.VertexSource.PathWriter();
            fontGlyph.originalVxs = ps.Vxs;
            int controlPointCount = 0;
            while (todoContourCount > 0)
            {
                int nextContour = outline.contours[startContour] + 1;
                bool isFirstPoint = true;
                FtVec2 secondControlPoint = new FtVec2();
                FtVec2 thirdControlPoint = new FtVec2();
                bool justFromCurveMode = false;
                //FT_Vector vpoint = new FT_Vector();
                for (; cpoint_index < nextContour; ++cpoint_index)
                {
                    FT_Vector vpoint = outline.points[cpoint_index];
                    byte vtag = outline.tags[cpoint_index];
                    bool has_dropout = (((vtag >> 2) & 0x1) != 0);
                    int dropoutMode = vtag >> 3;

                    Console.WriteLine(vpoint.ToString() + " " + vtag);

                    if ((vtag & 0x1) != 0)
                    {
                        //on curve
                        if (justFromCurveMode)
                        {
                            switch (controlPointCount)
                            {
                                case 1:
                                    {
                                        ps.Curve3(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                            vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                                    }
                                    break;
                                case 2:
                                    {
                                        ps.Curve4(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                           thirdControlPoint.x / FT_RESIZE, thirdControlPoint.y / FT_RESIZE,
                                           vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                                    }
                                    break;
                                default:
                                    {
                                        throw new NotSupportedException();
                                    }
                            }
                            controlPointCount = 0;
                            justFromCurveMode = false;
                        }
                        else
                        {
                            if (isFirstPoint)
                            {
                                isFirstPoint = false;
                                ps.MoveTo(vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                            }
                            else
                            {
                                ps.LineTo(vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                            }

                            if (has_dropout)
                            {
                                //printf("[%d] on,dropoutMode=%d: %d,y:%d \n", mm, dropoutMode, vpoint.x, vpoint.y);
                            }
                            else
                            {
                                //printf("[%d] on,x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                            }
                        }
                    }
                    else
                    {
                        switch (controlPointCount)
                        {
                            case 0:
                                {   //bit 1 set=> off curve, this is a control point
                                    //if this is a 2nd order or 3rd order control point
                                    if (((vtag >> 1) & 0x1) != 0)
                                    {
                                        //printf("[%d] bzc3rd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                        thirdControlPoint = new FtVec2(vpoint);
                                    }
                                    else
                                    {
                                        //printf("[%d] bzc2nd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                        secondControlPoint = new FtVec2(vpoint);
                                    }
                                }
                                break;
                            case 1:
                                {
                                    if (((vtag >> 1) & 0x1) != 0)
                                    {
                                        //printf("[%d] bzc3rd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                        thirdControlPoint = new FtVec2(vpoint);
                                    }
                                    else
                                    {
                                        //we already have prev second control point
                                        //so auto calculate line to 
                                        //between 2 point
                                        FtVec2 mid = GetMidPoint(secondControlPoint, vpoint);
                                        //----------
                                        //generate curve3
                                        ps.Curve3(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                            mid.x / FT_RESIZE, mid.y / FT_RESIZE);
                                        //------------------------
                                        controlPointCount--;
                                        //------------------------
                                        //printf("[%d] bzc2nd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                        secondControlPoint = new FtVec2(vpoint);
                                    }
                                }
                                break;
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                                break;
                        }

                        controlPointCount++;
                        justFromCurveMode = true;
                    }
                }
                //--------
                //close figure
                //if in curve mode
                if (justFromCurveMode)
                {
                    switch (controlPointCount)
                    {
                        case 0: break;
                        case 1:
                            {
                                ps.Curve3(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                    ps.LastMoveX, ps.LastMoveY);
                            }
                            break;
                        case 2:
                            {
                                ps.Curve4(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                   thirdControlPoint.x / FT_RESIZE, thirdControlPoint.y / FT_RESIZE,
                                   ps.LastMoveX, ps.LastMoveY);
                            }
                            break;
                        default:
                            { throw new NotSupportedException(); }
                    }
                    justFromCurveMode = false;
                    controlPointCount = 0;
                }
                ps.CloseFigure();
                //--------                   
                startContour++;
                todoContourCount--;
            }
        }