예제 #1
0
        //------------------------------------------------------------------------------------------07.02.2006
        /// <summary>Writes the RepObj to the buffer.</summary>
        /// <param name="e">Environment data</param>
        public void Write(PdfIndirectObject_PageContents.Environment e)
        {
            PdfIndirectObject_PageContents p = e.pdfIndirectObject_PageContents;
            RepArcBase repArcBase            = (RepArcBase)e.repObj;
            Double     rOfsX = repArcBase.rWidth * (-repArcBase.rAlignH + 0.5);
            Double     rOfsY = repArcBase.rHeight * (1 - repArcBase.rAlignV - 0.5);

            e.matrixD.Multiply(new MatrixD(1, 0, 0, 1, rOfsX, rOfsY));

            String sDrawCommand = null;

            if (repArcBase._penProp != null && repArcBase._penProp.rWidth != 0.0)
            {
                p.Write_Pen(repArcBase._penProp);
                if (repArcBase._brushProp != null)
                {
                    p.Write_Brush(repArcBase._brushProp);
                    sDrawCommand = "b"; // close, fill and stroke path
                }
                else
                {
                    sDrawCommand = (repArcBase is RepArc ? "S" : "s"); // stroke : close and stroke path
                }
            }
            else if (repArcBase._brushProp != null)
            {
                p.Write_Brush(repArcBase._brushProp);
                sDrawCommand = "f"; // fill path
            }
            else
            {
                return;
            }

            Double rA  = repArcBase.rWidth / 2;
            Double rA2 = rA * rA;
            Double rB  = repArcBase.rHeight / 2;
            Double rB2 = rB * rB;

            // start point: P0
            Double rAngle0 = RT.rRadianFromDegree(repArcBase._rStartAngle);
            Double rP0X, rP0Y;

            repArcBase.GetEllipseXY(rAngle0, out rP0X, out rP0Y);
            p.Command("q");
            p.Write_Matrix(e.matrixD);
            p.Command("cm");
            if (repArcBase is RepArc || repArcBase is RepCircle || repArcBase is RepEllipse)
            {
                p.Number(rP0X);  p.Space();  p.Number(rP0Y);
                p.Command("m");
            }
            else
            {
                p.Number(0);  p.Space();  p.Number(0);
                p.Command("m");
                p.Number(rP0X);  p.Space();  p.Number(rP0Y);
                p.Command("l");
            }

            Double r             = repArcBase._rSweepAngle / 180 * Math.PI;
            Int32  iNumberOfArcs = ((Int32)(r / (Math.PI / 3.0))) + 1;
            Double rSweepAngle   = r / iNumberOfArcs;

            for (Int32 iArc = 0; iArc < iNumberOfArcs; iArc++)
            {
                // end point: P3
                Double rAngle3 = rAngle0 + rSweepAngle;
                Double rP3X, rP3Y;
                repArcBase.GetEllipseXY(rAngle3, out rP3X, out rP3Y);

                Double rAngle05 = rAngle0 + rSweepAngle / 2.0;
                Double rMX, rMY;
                repArcBase.GetEllipseXY(rAngle05, out rMX, out rMY);


                Double rP1X, rP2X, rP1Y, rP2Y;
                Double rDenominator = rP0X * rP3Y - rP3X * rP0Y;
                Debug.Assert(!RT.bEquals(rDenominator, 0, 0.0001), "parallel tangents never appears if the sweep angle is less than PI/2");
                if (RT.bEquals(rP0Y, 0, 0.0001))
                {
                    Debug.Assert(!RT.bEquals(rP3Y, 0, 0.0001), "P0 and P3 on x-axis: never appears if the sweep angle is less than PI/2");
                    rP1X = rP0X;
                    rP2X = 8.0 / 3.0 * rMX - 4.0 / 3.0 * rP0X - rP3X / 3.0;
                    rP1Y = 8.0 / 3.0 * rMY - rB2 / rP3Y + rB2 * rP3X * (8.0 * rMX - 4 * rP0X - rP3X) / (3.0 * rA2 * rP3Y) - rP3Y / 3.0;
                    rP2Y = rB2 / rP3Y * (1 - rP2X * rP3X / rA2);
                }
                else if (RT.bEquals(rP3Y, 0, 0.0001))
                {
                    rP1X = 8.0 / 3.0 * rMX - rP0X / 3.0 - 4.0 / 3.0 * rP3X;
                    rP2X = rP3X;
                    rP1Y = rB2 / rP0Y * (1 - rP0X * rP1X / rA2);
                    rP2Y = 8.0 / 3.0 * rMY - rP0Y / 3.0 - rB2 / rP0Y + rB2 * rP0X * (8.0 * rMX - rP0X - 4 * rP3X) / (3.0 * rA2 * rP0Y);
                }
                else
                {
                    rP1X = (3.0 * rA2 * rB2 * (rP0Y + rP3Y)
                            + rA2 * rP0Y * rP3Y * (rP0Y + rP3Y - 8 * rMY)
                            + rB2 * rP3X * rP0Y * (rP0X + rP3X - 8 * rMX))
                           / (3 * rB2 * rDenominator);
                    rP2X = 8.0 / 3.0 * rMX - (rP0X + rP3X) / 3.0 - rP1X;

                    rP1Y = rB2 / rP0Y * (1 - rP0X * rP1X / rA2);
                    rP2Y = rB2 / rP3Y * (1 - rP2X * rP3X / rA2);
                }
                Debug.Assert(RT.bEquals(rMX, rP0X / 8.0 + 3.0 / 8.0 * rP1X + 3.0 / 8.0 * rP2X + rP3X / 8.0, 0.0001));
                Debug.Assert(RT.bEquals(rMY, rP0Y / 8.0 + 3.0 / 8.0 * rP1Y + 3.0 / 8.0 * rP2Y + rP3Y / 8.0, 0.0001));

                p.Number(rP1X);  p.Space();  p.Number(rP1Y);  p.Space();  p.Number(rP2X);  p.Space();  p.Number(rP2Y);  p.Space();
                p.Number(rP3X);  p.Space();  p.Number(rP3Y);
                p.Command("c");

                rAngle0 += rSweepAngle;
                rP0X     = rP3X;
                rP0Y     = rP3Y;
            }
            p.Command(sDrawCommand);
            p.Command("Q");
        }