//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 15JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Strokes the outline of a IShape using the settings of the current * Graphics2D context. * @param brush the brush used to fill the shape. * @param shape the IShape to be rendered. */ public void Fill(Brush brush, IShape shape) { if (brush != null) { _graphicsFP.SetBrush(brush._wrappedBrushFP); _defaultBrush = brush; } PathIterator pathIterator = shape.GetPathIterator(null); int[] coords = new int[6]; GraphicsPathFP graphicsPathFP = new GraphicsPathFP(); PointFP pointFP1 = new PointFP(); PointFP pointFPCtl1 = new PointFP(); PointFP pointFPCtl2 = new PointFP(); while (!pathIterator.IsDone()) { int type = pathIterator.CurrentSegment(coords); switch (type) { case PathIterator.SEG_MOVETO: pointFP1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddMoveTo(pointFP1); break; case PathIterator.SEG_CLOSE: graphicsPathFP.AddClose(); break; case PathIterator.SEG_LINETO: pointFP1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddLineTo(pointFP1); break; case PathIterator.SEG_QUADTO: pointFPCtl1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); pointFP1.Reset(coords[2] << SingleFP.DECIMAL_BITS, coords[3] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddQuadTo(pointFPCtl1, pointFP1); break; case PathIterator.SEG_CUBICTO: pointFPCtl1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); pointFPCtl2.Reset(coords[2] << SingleFP.DECIMAL_BITS, coords[3] << SingleFP.DECIMAL_BITS); pointFP1.Reset(coords[4] << SingleFP.DECIMAL_BITS, coords[5] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddCurveTo(pointFPCtl1, pointFPCtl2, pointFP1); break; } pathIterator.Next(); } _graphicsFP.FillPath(graphicsPathFP); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 15JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Strokes the outline of a IShape using the settings of the current * Graphics2D context. * @param pen the pen used to stroke the shape. * @param shape the IShape to be rendered. */ public void Draw(Pen pen, IShape shape) { SetGraphicsFPPenAttribute(pen); PathIterator pathIterator = shape.GetPathIterator(null); int[] coords = new int[6]; GraphicsPathFP graphicsPathFP = new GraphicsPathFP(); PointFP pointFP1 = new PointFP(); PointFP pointFPCtl1 = new PointFP(); PointFP pointFPCtl2 = new PointFP(); while (!pathIterator.IsDone()) { int type = pathIterator.CurrentSegment(coords); switch (type) { case PathIterator.SEG_MOVETO: pointFP1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddMoveTo(pointFP1); break; case PathIterator.SEG_CLOSE: graphicsPathFP.AddClose(); break; case PathIterator.SEG_LINETO: pointFP1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddLineTo(pointFP1); break; case PathIterator.SEG_QUADTO: pointFPCtl1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); pointFP1.Reset(coords[2] << SingleFP.DECIMAL_BITS, coords[3] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddQuadTo(pointFPCtl1, pointFP1); break; case PathIterator.SEG_CUBICTO: pointFPCtl1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); pointFPCtl2.Reset(coords[2] << SingleFP.DECIMAL_BITS, coords[3] << SingleFP.DECIMAL_BITS); pointFP1.Reset(coords[4] << SingleFP.DECIMAL_BITS, coords[5] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddCurveTo(pointFPCtl1, pointFPCtl2, pointFP1); break; } pathIterator.Next(); } _graphicsFP.DrawPath(graphicsPathFP); }
private static ArrayList PathToCurves(PathIterator pi) { ArrayList curves = new ArrayList(); int windingRule = pi.WindingRule; // coords array is big enough for holding: // coordinates returned from currentSegment (6) // OR // two subdivided quadratic curves (2+4+4=10) // AND // 0-1 horizontal splitting parameters // OR // 2 parametric equation derivative coefficients // OR // three subdivided cubic curves (2+6+6+6=20) // AND // 0-2 horizontal splitting parameters // OR // 3 parametric equation derivative coefficients double[] coords = new double[23]; double movx = 0, movy = 0; double curx = 0, cury = 0; double newx, newy; while (!pi.Done) { switch (pi.CurrentSegment(coords)) { case PathIterator_Fields.SEG_MOVETO: Curve.insertLine(curves, curx, cury, movx, movy); curx = movx = coords[0]; cury = movy = coords[1]; Curve.insertMove(curves, movx, movy); break; case PathIterator_Fields.SEG_LINETO: newx = coords[0]; newy = coords[1]; Curve.insertLine(curves, curx, cury, newx, newy); curx = newx; cury = newy; break; case PathIterator_Fields.SEG_QUADTO: newx = coords[2]; newy = coords[3]; Curve.insertQuad(curves, curx, cury, coords); curx = newx; cury = newy; break; case PathIterator_Fields.SEG_CUBICTO: newx = coords[4]; newy = coords[5]; Curve.insertCubic(curves, curx, cury, coords); curx = newx; cury = newy; break; case PathIterator_Fields.SEG_CLOSE: Curve.insertLine(curves, curx, cury, movx, movy); curx = movx; cury = movy; break; } pi.Next(); } Curve.insertLine(curves, curx, cury, movx, movy); AreaOp @operator; if (windingRule == PathIterator_Fields.WIND_EVEN_ODD) { @operator = new AreaOp.EOWindOp(); } else { @operator = new AreaOp.NZWindOp(); } return(@operator.calculate(curves, EmptyCurves)); }
private void Next(bool doNext) { int level; if (HoldIndex >= HoldEnd) { if (doNext) { Src.Next(); } if (Src.Done) { Done_Renamed = true; return; } HoldType = Src.CurrentSegment(Hold); LevelIndex = 0; Levels[0] = 0; } switch (HoldType) { case PathIterator_Fields.SEG_MOVETO: case PathIterator_Fields.SEG_LINETO: Curx = Hold[0]; Cury = Hold[1]; if (HoldType == PathIterator_Fields.SEG_MOVETO) { Movx = Curx; Movy = Cury; } HoldIndex = 0; HoldEnd = 0; break; case PathIterator_Fields.SEG_CLOSE: Curx = Movx; Cury = Movy; HoldIndex = 0; HoldEnd = 0; break; case PathIterator_Fields.SEG_QUADTO: if (HoldIndex >= HoldEnd) { // Move the coordinates to the end of the array. HoldIndex = Hold.Length - 6; HoldEnd = Hold.Length - 2; Hold[HoldIndex + 0] = Curx; Hold[HoldIndex + 1] = Cury; Hold[HoldIndex + 2] = Hold[0]; Hold[HoldIndex + 3] = Hold[1]; Hold[HoldIndex + 4] = Curx = Hold[2]; Hold[HoldIndex + 5] = Cury = Hold[3]; } level = Levels[LevelIndex]; while (level < Limit) { if (QuadCurve2D.GetFlatnessSq(Hold, HoldIndex) < Squareflat) { break; } EnsureHoldCapacity(4); QuadCurve2D.Subdivide(Hold, HoldIndex, Hold, HoldIndex - 4, Hold, HoldIndex); HoldIndex -= 4; // Now that we have subdivided, we have constructed // two curves of one depth lower than the original // curve. One of those curves is in the place of // the former curve and one of them is in the next // set of held coordinate slots. We now set both // curves level values to the next higher level. level++; Levels[LevelIndex] = level; LevelIndex++; Levels[LevelIndex] = level; } // This curve segment is flat enough, or it is too deep // in recursion levels to try to flatten any more. The // two coordinates at holdIndex+4 and holdIndex+5 now // contain the endpoint of the curve which can be the // endpoint of an approximating line segment. HoldIndex += 4; LevelIndex--; break; case PathIterator_Fields.SEG_CUBICTO: if (HoldIndex >= HoldEnd) { // Move the coordinates to the end of the array. HoldIndex = Hold.Length - 8; HoldEnd = Hold.Length - 2; Hold[HoldIndex + 0] = Curx; Hold[HoldIndex + 1] = Cury; Hold[HoldIndex + 2] = Hold[0]; Hold[HoldIndex + 3] = Hold[1]; Hold[HoldIndex + 4] = Hold[2]; Hold[HoldIndex + 5] = Hold[3]; Hold[HoldIndex + 6] = Curx = Hold[4]; Hold[HoldIndex + 7] = Cury = Hold[5]; } level = Levels[LevelIndex]; while (level < Limit) { if (CubicCurve2D.GetFlatnessSq(Hold, HoldIndex) < Squareflat) { break; } EnsureHoldCapacity(6); CubicCurve2D.Subdivide(Hold, HoldIndex, Hold, HoldIndex - 6, Hold, HoldIndex); HoldIndex -= 6; // Now that we have subdivided, we have constructed // two curves of one depth lower than the original // curve. One of those curves is in the place of // the former curve and one of them is in the next // set of held coordinate slots. We now set both // curves level values to the next higher level. level++; Levels[LevelIndex] = level; LevelIndex++; Levels[LevelIndex] = level; } // This curve segment is flat enough, or it is too deep // in recursion levels to try to flatten any more. The // two coordinates at holdIndex+6 and holdIndex+7 now // contain the endpoint of the curve which can be the // endpoint of an approximating line segment. HoldIndex += 6; LevelIndex--; break; } }