public LinearGradientBrush(Rectangle rect, Color color1, Color color2, float angle, int fillType) { _start = new Point(rect.X, rect.Y); _end = new Point(rect.X + rect.Width, rect.Y + rect.Height); _gradientTransform = new AffineTransform(); _fractions = new[] { 0, 100 }; _colors = new[] { color1, color2 }; bool opaque = true; for (int i = 0; i < _colors.Length; i++) { opaque = opaque && (_colors[i].GetAlpha() == 0xff); } _transparency = opaque ? Color.OPAQUE : Color.TRANSLUCENT; RectangleFP r = Utils.ToRectangleFP(rect); _wrappedBrushFP = new LinearGradientBrushFP(r.GetLeft(), r.GetTop(), r.GetRight(), r.GetBottom(), MathFP.ToRadians(SingleFP.FromFloat(angle))); for (int i = 0; i < _colors.Length; i++) { ((LinearGradientBrushFP)_wrappedBrushFP) .SetGradientColor(SingleFP.FromFloat(_fractions[i] / 255.0f), _colors[i]._value); } ((LinearGradientBrushFP)_wrappedBrushFP).UpdateGradientTable(); _wrappedBrushFP.SetMatrix(Utils.ToMatrixFP(_gradientTransform)); _wrappedBrushFP.FillMode = fillType; }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * * @param ff_sx * @param ff_sy * @param ff_ex * @param ff_ey */ private void Scanline(int ffSx, int ffSy, int ffEx, int ffEy) { var sx = ffSx >> (SingleFP.DECIMAL_BITS - RENDERER_FRAC_X); var ex = ffEx >> (SingleFP.DECIMAL_BITS - RENDERER_FRAC_X); var sy = (ffSy * RENDERER_FRAC_Y) >> SingleFP.DECIMAL_BITS; var ey = (ffEy * RENDERER_FRAC_Y) >> SingleFP.DECIMAL_BITS; var xmin = MathFP.Min(sx, ex); var xmax = MathFP.Max(sx, ex); var ymin = MathFP.Min(sy, ey); var ymax = MathFP.Max(sy, ey); var incx = ffSx < ffEx && ffSy < ffEy || ffSx >= ffEx && ffSy >= ffEy ? 1 : -1; var x = incx == 1 ? xmin : xmax; var dire = ffSy < ffEy ? 1 : 0; if (((ymin < 0) && (ymax < 0)) || ((ymin >= (_height * RENDERER_FRAC_Y)) && (ymax >= (_height * RENDERER_FRAC_Y)))) { return; } var n = MathFP.Abs(xmax - xmin); var d = MathFP.Abs(ymax - ymin); var i = d; ymax = MathFP.Min(ymax, _height * RENDERER_FRAC_Y); for (var y = ymin; y < ymax; y++) { if (y >= 0) { if (_scanIndex >= Scanbuf.Length) { var bufSize = _scanIndex / BUFFERSIZE; if ((_scanIndex + 1) % BUFFERSIZE != 0) { bufSize += 1; } ScanbufTmp = new int[bufSize * BUFFERSIZE]; Array.Copy(Scanbuf, 0, ScanbufTmp, 0, _scanIndex); Scanbuf = new int[bufSize * BUFFERSIZE]; Array.Copy(ScanbufTmp, 0, Scanbuf, 0, _scanIndex); } Scanbuf[_scanIndex++] = ((y / RENDERER_FRAC_Y) << (RENDERER_REAL_X + RENDERER_FRAC_X + 1)) | (MathFP.Max(0, MathFP.Min((_width * RENDERER_FRAC_X_FACTOR) - 1, x)) << 1) | dire; } i += n; if (i > d) { var idivd = (i - 1) / d; x += incx * idivd; i -= d * idivd; } } }
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 // --------- ------------------- ------------- ---------------------- // 09NOV2008 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Create an round rectangle path from given parameter. * @param ff_xmin * @param ff_ymin * @param ff_xmax * @param ff_ymax * @param ff_rx * @param ff_ry * @return */ public static GraphicsPathFP CreateRoundRect(int ffXmin, int ffYmin, int ffXmax, int ffYmax, int ffRx, int ffRy) { const int ffPi = MathFP.PI; var path = new GraphicsPathFP(); path.AddMoveTo(new PointFP(ffXmin + ffRx, ffYmin)); path.AddLineTo(new PointFP(ffXmax - ffRx, ffYmin)); var ffRmax = MathFP.Min(ffXmax - ffXmin, ffYmax - ffYmin) / 2; if (ffRx > ffRmax) { ffRx = ffRmax; } if (ffRy > ffRmax) { ffRy = ffRmax; } if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmax - ffRx * 2, ffYmin, ffXmax, ffYmin + ffRy * 2, (-ffPi) / 2, 0, false, false)); } path.AddLineTo(new PointFP(ffXmax, ffYmin + ffRy)); path.AddLineTo(new PointFP(ffXmax, ffYmax - ffRy)); if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmax - ffRx * 2, ffYmax - ffRy * 2, ffXmax, ffYmax, 0, ffPi / 2, false, false)); } path.AddLineTo(new PointFP(ffXmax - ffRx, ffYmax)); path.AddLineTo(new PointFP(ffXmin + ffRx, ffYmax)); if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmin, ffYmax - ffRy * 2, ffXmin + ffRx * 2, ffYmax, ffPi / 2, ffPi, false, false)); } path.AddLineTo(new PointFP(ffXmin, ffYmax - ffRy)); path.AddLineTo(new PointFP(ffXmin, ffYmin + ffRy)); if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmin, ffYmin, ffXmin + ffRx * 2, ffYmin + ffRy * 2, -ffPi, (-ffPi) / 2, false, false)); } path.AddClose(); return(path); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 09NOV2008 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * * @param point */ public override void LineTo(PointFP point) { var pntTemp = new PointFP(point); _ffXmin = MathFP.Min(_ffXmin, CurrentPoint().X); _ffXmax = MathFP.Max(_ffXmax, point.X); _ffYmin = MathFP.Min(_ffYmin, CurrentPoint().Y); _ffYmax = MathFP.Max(_ffYmax, point.Y); if (_transformMatrix != null) { pntTemp.Transform(_transformMatrix); } Scanline(_transformedPoint.X, _transformedPoint.Y, pntTemp.X, pntTemp.Y); _transformedPoint = pntTemp; base.LineTo(point); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- 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 // --------- ------------------- ------------- ---------------------- // 09NOV2008 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * @inheritDoc * @param x the x coordinate * @param y the y coordinate * @param singlePoint * @return the color at given position. */ public override int GetColorAt(int x, int y, bool singlePoint) { var p = new PointFP(x << SingleFP.DECIMAL_BITS, y << SingleFP.DECIMAL_BITS); _nextPt.X = p.X + SingleFP.ONE; _nextPt.Y = p.Y; var newCenterPt = new PointFP(_centerPt); if (_finalMatrix != null) { p.Transform(_finalMatrix); //newCenterPt.transform(finalMatrix); } _ffCurrpos = MathFP.Div(PointFP.Distance(p.X - newCenterPt.X, p.Y - newCenterPt.Y), _ffRadius); var pos = _ffCurrpos >> SingleFP.DECIMAL_BITS - RATIO_BITS; switch (FillMode) { case REFLECT: pos = pos % (RATIO_MAX * 2); pos = pos < 0 ? pos + RATIO_MAX * 2 : pos; pos = (pos < RATIO_MAX) ? pos : RATIO_MAX * 2 - pos; break; case REPEAT: pos = pos % RATIO_MAX; pos = pos < 0 ? pos + RATIO_MAX : pos; break; case NO_CYCLE: pos = pos < 0 ? 0 : (pos > RATIO_MAX ? RATIO_MAX : pos); break; } return(_gradientColors[pos]); }
private void DrawBuffer() { var curd = 0; var cure = 0; var cura = 0; var cula = 0; var cury = 0; var curx = 0; var count = _scanIndex; for (int c = 0; c <= count; c++) { var curs = c == count ? 0 : Scanbuf[c]; var newy = ((curs >> (RENDERER_REAL_X + RENDERER_FRAC_X + 1)) & RENDERER_REAL_Y_MASK); var newx = ((curs >> (RENDERER_FRAC_X + 1)) & RENDERER_REAL_X_MASK); if ((newx != curx) || (newy != cury)) { var alp = (256 * cure) / (RENDERER_FRAC_Y)+ (256 * cula) / (RENDERER_FRAC_Y * (RENDERER_FRAC_X_FACTOR - 1)) + (256 * cura) / (RENDERER_FRAC_Y * (RENDERER_FRAC_X_FACTOR - 1)); if (alp != 0) { if (_drawMode == MODE_XOR) { alp = (alp & 0x100) != 0 ? (0xFF - (alp & 0xFF)) : (alp & 0xFF); } else { alp = MathFP.Min(255, MathFP.Abs(alp)); } if (alp != 0) { MergePixels(curx, cury, 1, alp); } } cure = curd; if (newy == cury) { if (curd != 0) { alp = (256 * curd) / RENDERER_FRAC_Y; if (alp != 0) { if (_drawMode == MODE_XOR) { alp = (alp & 0x100) != 0 ? (0xFF - (alp & 0xFF)) : (alp & 0xFF); } else { alp = MathFP.Min(255, MathFP.Abs(alp)); } if (alp != 0) { MergePixels(curx + 1, cury, newx - curx - 1, alp); } } } } else { cury = newy; curd = cure = 0; } curx = newx; cura = cula = 0; } if ((curs & 1) != 0) { curd++; cula += ((~(curs >> 1)) & RENDERER_FRAC_X_MASK); } else { curd--; cura -= ((~(curs >> 1)) & RENDERER_FRAC_X_MASK); } } }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- 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); }