protected internal virtual void ExtendIfNeeded(int cmdsAddNum, int pntsAddNum) { if (cmds == null) { cmds = new sbyte[BLOCKSIZE]; } if (pnts == null) { pnts = new PointFP[BLOCKSIZE]; } if (cmdsSize + cmdsAddNum > cmds.Length) { sbyte[] newdata = new sbyte[cmds.Length + (cmdsAddNum > BLOCKSIZE?cmdsAddNum:BLOCKSIZE)]; if (cmdsSize > 0) { Array.Copy(cmds, 0, newdata, 0, cmdsSize); } cmds = newdata; } if (pntsSize + pntsAddNum > pnts.Length) { PointFP[] newdata = new PointFP[pnts.Length + (pntsAddNum > BLOCKSIZE?pntsAddNum:BLOCKSIZE)]; if (pntsSize > 0) { Array.Copy(pnts, 0, newdata, 0, pntsSize); } pnts = newdata; } }
private void CurveEnd(PointFP control1, PointFP control2, PointFP curveEnd) { drawingCurve = false; if (needDrawStartCap) { startCapP1 = new PointFP(curveBegin); startCapP2 = new PointFP(control1); //AddLineCap(control1, curveBegin, startLineCap); needDrawStartCap = false; } LineFP head = new LineFP(); LineFP tail = new LineFP(); CalcHeadTail(curveBegin, control1, head, new LineFP()); outline.AddMoveTo(head.P1); outline.AddPath(curvePath1); CalcHeadTail(control2, curveEnd, new LineFP(), tail); outline.AddLineTo(tail.P1); outline.AddLineTo(tail.P2); outline.ExtendIfNeeded(curvePath1.cmdsSize, curvePath1.pntsSize); int j = curvePath2.pntsSize - 1; for (int i = curvePath2.cmdsSize - 1; i >= 0; i--) { outline.AddLineTo(curvePath2.pnts[j--]); } outline.AddLineTo(head.P2); outline.AddClose(); curvePath1 = null; curvePath2 = null; lastCurveTail = null; lastPoint = new PointFP(control2); drawingCurve = false; }
private void AddLineCap(PointFP p1, PointFP p2, int lineCap) { if (lineCap == PenFP.LINECAP_BUTT || p1.Equals(p2)) { return; } int dx = p2.X - p1.X; int dy = p2.Y - p1.Y; int len = PointFP.Distance(dx, dy); PointFP[] cap = lineCap == PenFP.LINECAP_ROUND?GraphicsPathFP.roundCap:GraphicsPathFP.squareCap; dx = MathFP.Mul(ff_rad, MathFP.Div(dx, len)); dy = MathFP.Mul(ff_rad, MathFP.Div(dy, len)); MatrixFP m = new MatrixFP(dx, dx, dy, -dy, p2.X, p2.Y); outline.AddMoveTo(new PointFP(0, GraphicsPathFP.One).Transform(m)); for (int i = 0; i < cap.Length; i++) { outline.AddLineTo(new PointFP(cap[i]).Transform(m)); } outline.AddLineTo(new PointFP(0, -GraphicsPathFP.One).Transform(m)); outline.AddClose(); }
public virtual RectangleFP Union(PointFP p) { if (!IsEmpty()) { Reset(MathFP.Min(ff_xmin, p.X), MathFP.Max(ff_xmax, p.X), MathFP.Min(ff_ymin, p.Y), MathFP.Max(ff_ymax, p.Y)); } return(this); }
public override void MoveTo(PointFP point) { FinishCurrentSegment(); needDrawStartCap = true; closed = false; startCapP1 = startCapP2 = null; base.MoveTo(point); }
private void CurveBegin(PointFP control) { AddLineJoin(lastPoint, currPoint, control); drawingCurve = true; curvePath1 = new GraphicsPathFP(); curvePath2 = new GraphicsPathFP(); curveBegin = new PointFP(currPoint); }
public virtual void MoveTo(PointFP point) { if (!started) { startPoint.Reset(point); started = true; } currPoint.Reset(point); }
public override void MoveTo(PointFP point) { transformedPoint = new PointFP(point); if (transformMatrix != null) { transformedPoint.Transform(transformMatrix); } base.MoveTo(point); }
public LineFP GetHeadOutline(int ff_rad) { PointFP p = new PointFP(P1.X - P2.X, P1.Y - P2.Y); int len = Length; p.Reset(MathFP.Div(-p.Y, len), MathFP.Div(p.X, len)); p.Reset(MathFP.Mul(p.X, ff_rad), MathFP.Mul(p.Y, ff_rad)); return(new LineFP(P1.X - p.X, P1.Y - p.Y, P1.X + p.X, P1.Y + p.Y)); }
private void CalcHeadTail(PointFP p1, PointFP p2, LineFP head, LineFP tail) { LineFP curr = new LineFP(p1, p2); head.Reset(curr.GetHeadOutline(ff_rad)); int dx = p2.X - p1.X; int dy = p2.Y - p1.Y; tail.Reset(head.P1.X + dx, head.P1.Y + dy, head.P2.X + dx, head.P2.Y + dy); }
public override int GetColorAt(int x, int y, bool singlePoint) { int pos; PointFP p = new PointFP(x << SingleFP.DecimalBits, y << SingleFP.DecimalBits); PointFP p1 = null; if (!singlePoint) { p1 = new PointFP(p.X + SingleFP.One, p.Y); } if (finalMatrix != null) { p.Transform(finalMatrix); if (!singlePoint) { p1.Transform(finalMatrix); } } int width = bounds.Width; int height = bounds.Height; if (type == LINEAR_GRADIENT) { int v = p.X + ff_length / 2; if (v < 0) { v = 0; } else if (v > ff_length - 1) { v = ff_length - 1; } ff_currpos = (int)(((long)v << RATIO_BITS + SingleFP.DecimalBits) / ff_length); if (!singlePoint) { ff_deltapos = (int)(((long)(p1.X - p.X) << RATIO_BITS + SingleFP.DecimalBits) / ff_length); } pos = ff_currpos >> SingleFP.DecimalBits; } else { ff_currpos = PointFP.Distance(p.X, p.Y); if (!singlePoint) { ff_deltapos = PointFP.Distance(p1.X, p1.Y) - ff_currpos; } //if (ff_currpos > SingleFP.One - 1) pos = SingleFP.One - 1; pos = ff_currpos >> SingleFP.DecimalBits - RATIO_BITS; } //pos >>= BrushFP.XY_MAX_BITS - RATIO_BITS; pos = pos < 0?0:(pos > RATIO_MAX?RATIO_MAX:pos); return(gradientColors[pos]); }
public void AddCurveTo(PointFP control, PointFP point) { if (control.Equals(point)) { AddLineTo(point); return; } ExtendIfNeeded(1, 2); cmds[cmdsSize++] = CMD_QCURVETO; pnts[pntsSize++] = new PointFP(control); pnts[pntsSize++] = new PointFP(point); }
public override bool Equals(System.Object obj) { PointFP p = (PointFP)obj; if (p != null) { return(X == p.X && Y == p.Y); } else { return(false); } }
static GraphicsPathFP() { One = SingleFP.One; roundCap[0] = new PointFP(25080, 60547); roundCap[1] = new PointFP(46341, 46341); roundCap[2] = new PointFP(60547, 25080); roundCap[3] = new PointFP(One, 0); roundCap[4] = new PointFP(60547, -25080); roundCap[5] = new PointFP(46341, -46341); roundCap[6] = new PointFP(25080, -60547); squareCap[0] = new PointFP(One, One); squareCap[1] = new PointFP(One, -One); }
public void AddPath(GraphicsPathFP path) { if (path.cmdsSize > 0) { ExtendIfNeeded(path.cmdsSize, path.pntsSize); Array.Copy(path.cmds, 0, cmds, cmdsSize, path.cmdsSize); for (int i = 0; i < path.pntsSize; i++) { pnts[i + pntsSize] = new PointFP(path.pnts[i]); } cmdsSize += path.cmdsSize; pntsSize += path.pntsSize; } }
public LineFP GetTailOutline(int ff_rad) { PointFP c = Center; PointFP p = new PointFP(P2.X - c.X, P2.Y - c.Y); p.Reset(p.Y, -p.X); int dis = PointFP.Distance(PointFP.Origin, p); if (dis == 0) { dis = 1; } p.Reset(MathFP.Div(MathFP.Mul(p.X, ff_rad), dis), MathFP.Div(MathFP.Mul(p.Y, ff_rad), dis)); return(new LineFP(P2.X - p.X, P2.Y - p.Y, P2.X + p.X, P2.Y + p.Y)); }
public GraphicsPathFP(GraphicsPathFP from) { cmdsSize = from.cmdsSize; pntsSize = from.pntsSize; if (cmdsSize > 0) { cmds = new sbyte[cmdsSize]; pnts = new PointFP[pntsSize]; Array.Copy(from.cmds, 0, cmds, 0, cmdsSize); for (int i = 0; i < pntsSize; i++) { pnts[i] = new PointFP(from.pnts[i]); } } }
private void AddLineJoin(PointFP lastPoint, PointFP currPoint, PointFP nextPoint) { if (lastPoint == null || currPoint == null || nextPoint == null || nextPoint.Equals(currPoint) || lastPoint.Equals(currPoint)) { return; } PointFP p1 = null, p2 = null; LineFP head, tail, lastHead, lastTail; CalcHeadTail(currPoint, nextPoint, head = new LineFP(), tail = new LineFP()); CalcHeadTail(lastPoint, currPoint, lastHead = new LineFP(), lastTail = new LineFP()); bool cross1, cross2, needLineJoin = false; PointFP pi1 = new PointFP(); PointFP pi2 = new PointFP(); cross1 = LineFP.Intersects(new LineFP(head.P1, tail.P1), new LineFP(lastHead.P1, lastTail.P1), pi1); cross2 = LineFP.Intersects(new LineFP(head.P2, tail.P2), new LineFP(lastHead.P2, lastTail.P2), pi2); if (cross1 && !cross2 && pi1.X != SingleFP.NaN) { p1 = lastTail.P2; p2 = head.P2; needLineJoin = true; } else if (!cross1 && cross2 && pi2.X != SingleFP.NaN) { p1 = lastTail.P1; p2 = head.P1; needLineJoin = true; } if (needLineJoin) { outline.AddMoveTo(cross1 ? pi1 : pi2); outline.AddLineTo(cross1 ? p2 : p1); if (lineJoin == PenFP.LINEJOIN_MITER) { outline.AddLineTo(cross1 ? pi2 : pi1); } outline.AddLineTo(cross1 ? p1 : p2); outline.AddClose(); if (lineJoin == PenFP.LINEJOIN_ROUND) { AddLineCap(cross2 ? pi2 : pi1, currPoint, PenFP.LINECAP_ROUND); } } }
public virtual void CurveTo(PointFP control1, PointFP control2, PointFP point) { PointFP tmp1 = new PointFP(currPoint.X - control1.X * 2 + control2.X, currPoint.Y - control1.Y * 2 + control2.Y); PointFP tmp2 = new PointFP((control1.X - control2.X) * 3 - currPoint.X + point.X, (control1.Y - control2.Y) * 3 - currPoint.Y + point.Y); PointFP f = new PointFP(currPoint); PointFP df = new PointFP((control1.X - currPoint.X) * 3 / SUBDIVIDE + tmp1.X * 3 / SUBDIVIDE2 + tmp2.X / SUBDIVIDE3, (control1.Y - currPoint.Y) * 3 / SUBDIVIDE + tmp1.Y * 3 / SUBDIVIDE2 + tmp2.Y / SUBDIVIDE3); PointFP ddf = new PointFP(tmp1.X * 6 / SUBDIVIDE2 + tmp2.X * 6 / SUBDIVIDE3, tmp1.Y * 6 / SUBDIVIDE2 + tmp2.Y * 6 / SUBDIVIDE3); PointFP dddf = new PointFP(tmp2.X * 6 / SUBDIVIDE3, tmp2.Y * 6 / SUBDIVIDE3); for (int c = 0; c < SUBDIVIDE - 1; c++) { f.Add(df); df.Add(ddf); ddf.Add(dddf); LineTo(f); } LineTo(point); }
public static GraphicsPathFP CreateSmoothCurves(PointFP[] points, int offset, int numberOfSegments, int ff_factor, bool closed) { int len = points.Length; GraphicsPathFP path = new GraphicsPathFP(); if (numberOfSegments < 1 || numberOfSegments > points.Length - 1 || offset < 0 || offset + numberOfSegments > len - 1) { return(path); } PointFP[] PC1s = new PointFP[points.Length]; PointFP[] PC2s = new PointFP[points.Length]; if (!closed) { PC1s[0] = points[0]; PC2s[len - 1] = points[len - 1]; } else { PC1s[0] = CalcControlPoint(points[len - 1], points[0], points[1], ff_factor); PC2s[0] = CalcControlPoint(points[1], points[0], points[len - 1], ff_factor); PC1s[len - 1] = CalcControlPoint(points[len - 2], points[len - 1], points[0], ff_factor); PC2s[len - 1] = CalcControlPoint(points[0], points[len - 1], points[len - 2], ff_factor); } for (int i = 1; i < len - 1; i++) { PC1s[i] = CalcControlPoint(points[i - 1], points[i], points[i + 1], ff_factor); PC2s[i] = CalcControlPoint(points[i + 1], points[i], points[i - 1], ff_factor); } path.AddMoveTo(points[offset]); for (int i = 0; i < numberOfSegments; i++) { path.AddCurveTo(PC1s[offset + i], PC2s[offset + i + 1], points[offset + i + 1]); } if (closed) { path.AddCurveTo(PC1s[len - 1], PC2s[0], points[0]); path.AddClose(); } return(path); }
public void AddCurveTo(PointFP control1, PointFP control2, PointFP point) { if (pnts[pntsSize - 1].Equals(control1)) { AddCurveTo(control2, point); return; } if (point.Equals(control2)) { AddCurveTo(control1, point); return; } ExtendIfNeeded(1, 3); cmds[cmdsSize++] = CMD_CCURVETO; pnts[pntsSize++] = new PointFP(control1); pnts[pntsSize++] = new PointFP(control2); pnts[pntsSize++] = new PointFP(point); }
public virtual void Visit(GraphicsPathIterator iterator) { if (iterator != null) { PointFP p0 = new PointFP(); PointFP p1 = new PointFP(); PointFP p2 = new PointFP(); iterator.Begin(); int j = 0; for (int i = 0; i < cmdsSize; i++) { switch (cmds[i]) { case CMD_NOP: break; case CMD_MOVETO: iterator.MoveTo(pnts[j++]); break; case CMD_LINETO: iterator.LineTo(pnts[j++]); break; case CMD_QCURVETO: iterator.CurveTo(pnts[j++], pnts[j++]); break; case CMD_CCURVETO: iterator.CurveTo(pnts[j++], pnts[j++], pnts[j++]); break; case CMD_CLOSE: iterator.Close(); break; default: return; } } iterator.End(); } }
public override void LineTo(PointFP point) { //PointFP a = new PointFP(CurrentPoint); PointFP pntTemp = new PointFP(point); ff_xmin = MathFP.Min(ff_xmin, CurrentPoint.X); ff_xmax = MathFP.Max(ff_xmax, point.X); ff_ymin = MathFP.Min(ff_ymin, CurrentPoint.Y); ff_ymax = MathFP.Max(ff_ymax, point.Y); if (transformMatrix != null) { pntTemp.Transform(transformMatrix); //b.Transform(transformMatrix); } Scanline(transformedPoint.X, transformedPoint.Y, pntTemp.X, pntTemp.Y); transformedPoint = pntTemp; base.LineTo(point); }
public virtual void CurveTo(PointFP control, PointFP point) { // Compute forward difference values for a quadratic // curve of type A*(1-t)^2 + 2*B*t*(1-t) + C*t^2 PointFP f = new PointFP(currPoint); PointFP tmp = new PointFP((currPoint.X - control.X * 2 + point.X) / SUBDIVIDE2, (currPoint.Y - control.Y * 2 + point.Y) / SUBDIVIDE2); PointFP ddf = new PointFP(tmp.X * 2, tmp.Y * 2); PointFP df = new PointFP(tmp.X + (control.X - currPoint.X) * 2 / SUBDIVIDE, tmp.Y + (control.Y - currPoint.Y) * 2 / SUBDIVIDE); for (int c = 0; c < SUBDIVIDE - 1; c++) { f.Add(df); df.Add(ddf); LineTo(f); } // We specify the last point manually since // we obtain rounding errors during the // forward difference computation. LineTo(point); }
public GradientBrushFP(int ff_xmin, int ff_ymin, int ff_xmax, int ff_ymax, int ff_angle, int type) { bounds.Reset(ff_xmin, ff_ymin, ff_xmax == ff_xmin ? ff_xmin + 1 : ff_xmax, ff_ymax == ff_ymin ? ff_ymin + 1 : ff_ymax); matrix = new MatrixFP(); matrix.Translate(-(ff_xmin + ff_xmax) / 2, -(ff_ymin + ff_ymax) / 2); matrix.Rotate(-ff_angle); this.type = type; if (type == RADIAL_GRADIENT) { matrix.Scale(MathFP.Div(SingleFP.One, bounds.Width), MathFP.Div(SingleFP.One, bounds.Height)); } int ff_ang = MathFP.Atan(MathFP.Div(bounds.Height, bounds.Width == 0 ? 1 : bounds.Width)); int ff_len = PointFP.Distance(bounds.Height, bounds.Width); ff_length = MathFP.Mul(ff_len, MathFP.Max( MathFP.Abs(MathFP.Cos(ff_angle - ff_ang)), MathFP.Abs(MathFP.Cos(ff_angle + ff_ang)))); }
public override void LineTo(PointFP point) { if (point.Equals(currPoint)) { return; } LineFP head, tail; CalcHeadTail(currPoint, point, head = new LineFP(), tail = new LineFP()); if (drawingCurve) { if (lastCurveTail != null) { curvePath1.AddLineTo(lastCurveTail.P1); curvePath2.AddLineTo(lastCurveTail.P2); } lastCurveTail = new LineFP(tail); } else { if (needDrawStartCap) { //AddLineCap(point, currPoint, startLineCap); startCapP1 = new PointFP(currPoint); startCapP2 = new PointFP(point); needDrawStartCap = false; } AddLineJoin(lastPoint, currPoint, point); outline.AddMoveTo(head.P1); outline.AddLineTo(tail.P1); outline.AddLineTo(tail.P2); outline.AddLineTo(head.P2); outline.AddLineTo(head.P1); outline.AddClose(); lastPoint = new PointFP(currPoint); } base.LineTo(point); }
public static PointFP CalcControlPoint(PointFP p1, PointFP p2, PointFP p3, int ff_factor) { PointFP ps = new PointFP(p2.X + MathFP.Mul(p2.X - p1.X, ff_factor), p2.Y + MathFP.Mul(p2.Y - p1.Y, ff_factor)); return(new LineFP(new LineFP(p2, ps).Center, new LineFP(p2, p3).Center).Center); }
public void AddLineTo(PointFP point) { ExtendIfNeeded(1, 1); cmds[cmdsSize++] = CMD_LINETO; pnts[pntsSize++] = new PointFP(point); }
public virtual void LineTo(PointFP point) { currPoint.Reset(point); }
public void Reset(PointFP p1, PointFP p2) { this.P1.Reset(p1); this.P2.Reset(p2); }