private static PointFP CalcControlPoint(PointFP p1, PointFP p2,
                                                PointFP p3, int ffFactor)
        {
            var ps = new PointFP(p2.X + MathFP.Mul(p2.X - p1.X, ffFactor),
                                 p2.Y + MathFP.Mul(p2.Y - p1.Y, ffFactor));

            return(new LineFP((new LineFP(p2, ps)).GetCenter(),
                              (new LineFP(p2, p3)).GetCenter()).GetCenter());
        }
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 13JUN2009  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Create the gradient brush.
         * @param ff_xmin the top left coordinate.
         * @param ff_ymin the top left coordinate.
         * @param ff_xmax the bottom right coordinate.
         * @param ff_ymax the bottom right coordinate.
         * @param ff_angle the angle for this gradient.
         * @param type  the type of the gradient brush.
         */
        public LinearGradientBrushFP(int ffXmin, int ffYmin, int ffXmax, int ffYmax,
                                     int ffAngle)
        {
            _bounds.Reset(ffXmin, ffYmin,
                          ffXmax == ffXmin ? ffXmin + 1 : ffXmax,
                          ffYmax == ffYmin ? ffYmin + 1 : ffYmax);
            _matrix = new MatrixFP();
            _centerPt.Reset(ffXmin + (ffXmax - ffXmin) / 2,
                            ffYmin + (ffYmax - ffYmin) / 2);
            _matrix.Translate(-_centerPt.X, -_centerPt.Y);
            _matrix.Rotate(-ffAngle);
            //matrix.translate((ff_xmin + ff_xmax) / 2,(ff_ymin + ff_ymax) / 2);

            var ffAng = MathFP.Atan(MathFP.Div(_bounds.GetHeight(),
                                               _bounds.GetWidth() == 0 ? 1 : _bounds.GetWidth()));
            var ffLen = PointFP.Distance(_bounds.GetHeight(), _bounds.GetWidth());

            _ffLength = MathFP.Mul(ffLen, MathFP.Max(
                                       MathFP.Abs(MathFP.Cos(ffAngle - ffAng)),
                                       MathFP.Abs(MathFP.Cos(ffAngle + ffAng))));
        }
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 13JUN2009  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Create arc path.
         * @param ff_xmin
         * @param ff_ymin
         * @param ff_xmax
         * @param ff_ymax
         * @param ff_startangle
         * @param ff_sweepangle
         * @param closed
         * @param standalone
         * @return
         */
        public static GraphicsPathFP CreateArc(int ffXmin, int ffYmin,
                                               int ffXmax, int ffYmax, int ffStartangle,
                                               int ffSweepangle, bool closed, bool standalone)
        {
            if (ffSweepangle < 0)
            {
                ffStartangle += ffSweepangle;
                ffSweepangle  = -ffSweepangle;
            }
            var segments = MathFP.Round(MathFP.Div(4 * MathFP.Abs(ffSweepangle),
                                                   MathFP.PI)) >> SingleFP.DECIMAL_BITS;

            if (segments == 0)
            {
                segments = 1;
            }
            var path      = new GraphicsPathFP();
            var ffDarg    = ffSweepangle / segments;
            var ffArg     = ffStartangle;
            var ffLastcos = MathFP.Cos(ffStartangle);
            var ffLastsin = MathFP.Sin(ffStartangle);
            var ffXc      = (ffXmin + ffXmax) / 2;
            var ffYc      = (ffYmin + ffYmax) / 2;
            var ffRx      = (ffXmax - ffXmin) / 2;
            var ffRy      = (ffYmax - ffYmin) / 2;
            var ffRxbeta  = MathFP.Mul(17381, ffRx);
            var ffRybeta  = MathFP.Mul(17381, ffRy);

            if (closed)
            {
                path.AddMoveTo(new PointFP(ffXc, ffYc));
            }

            for (var i = 1; i <= segments; i++)
            {
                ffArg = i == segments ? ffStartangle + ffSweepangle
                        : ffArg + ffDarg;
                var ffCurrcos = MathFP.Cos(ffArg);
                var ffCurrsin = MathFP.Sin(ffArg);
                var ffX1      = ffXc + MathFP.Mul(ffRx, ffLastcos);
                var ffY1      = ffYc + MathFP.Mul(ffRy, ffLastsin);
                var ffX2      = ffXc + MathFP.Mul(ffRx, ffCurrcos);
                var ffY2      = ffYc + MathFP.Mul(ffRy, ffCurrsin);
                if (i == 1)
                {
                    if (closed)
                    {
                        path.AddLineTo(new PointFP(ffX1, ffY1));
                    }
                    else if (standalone)
                    {
                        path.AddMoveTo(new PointFP(ffX1, ffY1));
                    }
                }

                path.AddCurveTo(
                    new PointFP(ffX1 - MathFP.Mul(ffRxbeta, ffLastsin),
                                ffY1 + MathFP.Mul(ffRybeta, ffLastcos)),
                    new PointFP(ffX2 + MathFP.Mul(ffRxbeta, ffCurrsin),
                                ffY2 - MathFP.Mul(ffRybeta, ffCurrcos)),
                    new PointFP(ffX2, ffY2));
                ffLastcos = ffCurrcos;
                ffLastsin = ffCurrsin;
            }
            if (closed)
            {
                path.AddClose();
            }
            return(path);
        }