public void Init(double x1, double y1, double cx, double cy, double x2, double y2) { _start_x = x1; _start_y = y1; _end_x = x2; _end_y = y2; double dx1 = cx - x1; double dy1 = cy - y1; double dx2 = x2 - cx; double dy2 = y2 - cy; double len = Math.Sqrt(dx1 * dx1 + dy1 * dy1) + Math.Sqrt(dx2 * dx2 + dy2 * dy2); _num_steps = (int)AggMath.uround(len * 0.25 * _scale); if (_num_steps < 4) { _num_steps = 4; } double eachIncStep = 1.0 / _num_steps; double eachIncStep2 = eachIncStep * eachIncStep; double tmpx = (x1 - cx * 2.0 + x2) * eachIncStep2; double tmpy = (y1 - cy * 2.0 + y2) * eachIncStep2; _saved_fx = _fx = x1; _saved_fy = _fy = y1; _saved_dfx = _dfx = tmpx + (cx - x1) * (2.0 * eachIncStep); _saved_dfy = _dfy = tmpy + (cy - y1) * (2.0 * eachIncStep); _ddfx = tmpx * 2.0; _ddfy = tmpy * 2.0; _step = _num_steps; }
// Vertex Source Interface void RewindZero() { if (m_status == StrokeMath.Status.Init) { vertexDistanceList.Close(true); if (m_auto_detect) { if (m_orientation == EndVertexOrientation.Unknown) { m_orientation = (AggMath.CalculatePolygonArea(vertexDistanceList) > 0.0) ? EndVertexOrientation.CCW : EndVertexOrientation.CW; } } switch (m_orientation) { case EndVertexOrientation.CCW: { m_stroker.Width = m_width; } break; case EndVertexOrientation.CW: { m_stroker.Width = -m_width; } break; } } m_status = StrokeMath.Status.Ready; m_src_vertex = 0; }
public void PineHLine(int xc, int yc, int xp1, int yp1, int xp2, int yp2, int xh1, int yh1, int xh2) { if (doClipping && ClipLiangBarsky.Flags(xc, yc, clippingRectangle) != 0) { return; } byte[] covers = new byte[MAX_HALF_WIDTH * 2 + 4]; int index0 = 0; int index1 = 0; int x = xh1 << LineAA.SUBPIXEL_SHIFT; int y = yh1 << LineAA.SUBPIXEL_SHIFT; int w = SubPixelWidth; DistanceInterpolator00 di = new DistanceInterpolator00(xc, yc, xp1, yp1, xp2, yp2, x, y); x += LineAA.SUBPIXEL_SCALE / 2; y += LineAA.SUBPIXEL_SCALE / 2; int xh0 = xh1; int dx = x - xc; int dy = y - yc; do { int d = (int)(AggMath.fast_sqrt(dx * dx + dy * dy)); covers[index1] = 0; if (di.Distance1 <= 0 && di.Distance2 > 0 && d <= w) { covers[index1] = (byte)GetCover(d); } ++index1; dx += LineAA.SUBPIXEL_SCALE; di.IncX(); }while (++xh1 <= xh2); destImageSurface.BlendSolidHSpan(xh0, yh1, index1 - index0, Color, covers, index0); }
void BuildEndCap( double x0, double y0, double x1, double y1, List <Vector> outputVectors) { switch (LineCapStyle) { default: throw new NotSupportedException(); case LineCap.Butt: break; case LineCap.Square: break; case LineCap.Round: { //------------------------ //x0,y0 -> end of line 1 //x1,y1 -> end of line 2 //------------------------ double c_x = (x0 + x1) / 2; double c_y = (y0 + y1) / 2; Vector2 delta = new Vector2(x1 - c_x, y1 - c_y); ArcGenerator.GenerateArcNew(outputVectors, c_x, c_y, delta, AggMath.deg2rad(180)); } break; } }
//--------------------------------------------------------------------- public void Setup(double r, double fx, double fy) { m_r = AggMath.iround(r * GradientSpanGen.GR_SUBPIX_SCALE); m_fx = AggMath.iround(fx * GradientSpanGen.GR_SUBPIX_SCALE); m_fy = AggMath.iround(fy * GradientSpanGen.GR_SUBPIX_SCALE); UpdateValues(); }
//-------------------------------------------------------------------- // Sets the triangle and dilates it if needed. // The trick here is to calculate beveled joins in the vertices of the // triangle and render it as a 6-vertex polygon. // It's necessary to achieve numerical stability. // However, the coordinates to interpolate colors are calculated // as miter joins (calc_intersection). public void SetTriangle(double x1, double y1, double x2, double y2, double x3, double y3) { _coord_0.x = _x[0] = x1; _coord_0.y = _y[0] = y1; _coord_1.x = _x[1] = x2; _coord_1.y = _y[1] = y2; _coord_2.x = _x[2] = x3; _coord_2.y = _y[2] = y3; _cmd[0] = VertexCmd.MoveTo; _cmd[1] = VertexCmd.LineTo; _cmd[2] = VertexCmd.LineTo; _cmd[3] = VertexCmd.NoMore; if (DilationValue != 0.0) { AggMath.DilateTriangle(_coord_0.x, _coord_0.y, _coord_1.x, _coord_1.y, _coord_2.x, _coord_2.y, _x, _y, DilationValue); AggMath.CalcIntersect(_x[4], _y[4], _x[5], _y[5], _x[0], _y[0], _x[1], _y[1], out _coord_0.x, out _coord_0.y); AggMath.CalcIntersect(_x[0], _y[0], _x[1], _y[1], _x[2], _y[2], _x[3], _y[3], out _coord_1.x, out _coord_1.y); AggMath.CalcIntersect(_x[2], _y[2], _x[3], _y[3], _x[4], _y[4], _x[5], _y[5], out _coord_2.x, out _coord_2.y); _cmd[3] = VertexCmd.LineTo; _cmd[4] = VertexCmd.LineTo; _cmd[5] = VertexCmd.LineTo; _cmd[6] = VertexCmd.NoMore; } }
public override void Line0(LineParameters lp) { if (doClipping) { int x1 = lp.x1; int y1 = lp.y1; int x2 = lp.x2; int y2 = lp.y2; int flags = ClipLiangBarsky.ClipLineSegment(ref x1, ref y1, ref x2, ref y2, clippingRectangle); if ((flags & 4) == 0) { if (flags != 0) { LineParameters lp2 = new LineParameters(x1, y1, x2, y2, AggBasics.uround(AggMath.calc_distance(x1, y1, x2, y2))); Line0NoClip(lp2); } else { Line0NoClip(lp); } } } else { Line0NoClip(lp); } }
public void Init(double x1, double y1, double cx, double cy, double x2, double y2) { m_start_x = x1; m_start_y = y1; m_end_x = x2; m_end_y = y2; double dx1 = cx - x1; double dy1 = cy - y1; double dx2 = x2 - cx; double dy2 = y2 - cy; double len = Math.Sqrt(dx1 * dx1 + dy1 * dy1) + Math.Sqrt(dx2 * dx2 + dy2 * dy2); m_num_steps = (int)AggMath.uround(len * 0.25 * m_scale); if (m_num_steps < 4) { m_num_steps = 4; } double subdivide_step = 1.0 / m_num_steps; double subdivide_step2 = subdivide_step * subdivide_step; double tmpx = (x1 - cx * 2.0 + x2) * subdivide_step2; double tmpy = (y1 - cy * 2.0 + y2) * subdivide_step2; m_saved_fx = m_fx = x1; m_saved_fy = m_fy = y1; m_saved_dfx = m_dfx = tmpx + (cx - x1) * (2.0 * subdivide_step); m_saved_dfy = m_dfy = tmpy + (cy - y1) * (2.0 * subdivide_step); m_ddfx = tmpx * 2.0; m_ddfy = tmpy * 2.0; m_step = m_num_steps; }
public override void SemiDotHLine(CompareFunction cmp, int xc1, int yc1, int xc2, int yc2, int x1, int y1, int x2) { byte[] covers = new byte[MAX_HALF_WIDTH * 2 + 4]; int offset0 = 0; int offset1 = 0; int x = x1 << LineAA.SUBPIXEL_SHIFT; int y = y1 << LineAA.SUBPIXEL_SHIFT; int w = SubPixelWidth; DistanceInterpolator0 di = new DistanceInterpolator0(xc1, yc1, xc2, yc2, x, y); x += LineAA.SUBPIXEL_SCALE / 2; y += LineAA.SUBPIXEL_SCALE / 2; int x0 = x1; int dx = x - xc1; int dy = y - yc1; do { int d = (int)(AggMath.fast_sqrt(dx * dx + dy * dy)); covers[offset1] = 0; if (cmp(di.Distance) && d <= w) { covers[offset1] = (byte)GetCover(d); } ++offset1; dx += LineAA.SUBPIXEL_SCALE; di.IncX(); }while (++x1 <= x2); destImageSurface.BlendSolidHSpan(x0, y1, offset1 - offset0, Color, covers, offset0); }
//--------------------------------------------------------------------- public DistanceInterpolator3(int x1, int y1, int x2, int y2, int sx, int sy, int ex, int ey, int x, int y) { unchecked { _dx = (x2 - x1); _dy = (y2 - y1); _dx_start = (LineAA.Mr(sx) - LineAA.Mr(x1)); _dy_start = (LineAA.Mr(sy) - LineAA.Mr(y1)); _dx_end = (LineAA.Mr(ex) - LineAA.Mr(x2)); _dy_end = (LineAA.Mr(ey) - LineAA.Mr(y2)); _dist = (AggMath.iround((double)(x + LineAA.SUBPIXEL_SCALE / 2 - x2) * (double)(_dy) - (double)(y + LineAA.SUBPIXEL_SCALE / 2 - y2) * (double)(_dx))); _dist_start = ((LineAA.Mr(x + LineAA.SUBPIXEL_SCALE / 2) - LineAA.Mr(sx)) * _dy_start - (LineAA.Mr(y + LineAA.SUBPIXEL_SCALE / 2) - LineAA.Mr(sy)) * _dx_start); _dist_end = ((LineAA.Mr(x + LineAA.SUBPIXEL_SCALE / 2) - LineAA.Mr(ex)) * _dy_end - (LineAA.Mr(y + LineAA.SUBPIXEL_SCALE / 2) - LineAA.Mr(ey)) * _dx_end); _dx <<= LineAA.SUBPIXEL_SHIFT; _dy <<= LineAA.SUBPIXEL_SHIFT; _dx_start <<= LineAA.MR_SUBPIXEL_SHIFT; _dy_start <<= LineAA.MR_SUBPIXEL_SHIFT; _dx_end <<= LineAA.MR_SUBPIXEL_SHIFT; _dy_end <<= LineAA.MR_SUBPIXEL_SHIFT; } }
// public void SetFilterOffset(double dx, double dy) { _dx_dbl = dx; _dy_dbl = dy; _dx_int = AggMath.iround(dx * img_subpix_const.SCALE); _dy_int = AggMath.iround(dy * img_subpix_const.SCALE); }
public static void Bisectrix(LineParameters l1, LineParameters l2, out int x, out int y) { double k = (double)(l2.len) / (double)(l1.len); double tx = l2.x2 - (l2.x1 - l1.x1) * k; double ty = l2.y2 - (l2.y1 - l1.y1) * k; //All bisectrices must be on the right of the line //If the next point is on the left (l1 => l2.2) //then the bisectix should be rotated by 180 degrees. if ((double)(l2.x2 - l2.x1) * (double)(l2.y1 - l1.y1) < (double)(l2.y2 - l2.y1) * (double)(l2.x1 - l1.x1) + 100.0) { tx -= (tx - l2.x1) * 2.0; ty -= (ty - l2.y1) * 2.0; } // Check if the bisectrix is too short double dx = tx - l2.x1; double dy = ty - l2.y1; if ((int)Math.Sqrt(dx * dx + dy * dy) < SUBPIXEL_SCALE) { x = (l2.x1 + l2.x1 + (l2.y1 - l1.y1) + (l2.y2 - l2.y1)) >> 1; y = (l2.y1 + l2.y1 - (l2.x1 - l1.x1) - (l2.x2 - l2.x1)) >> 1; return; } x = AggMath.iround(tx); y = AggMath.iround(ty); }
public override void MouseDown(int mx, int my, bool isRightButton) { double x = mx; double y = my; int i; for (i = 0; i < 3; i++) { if (Math.Sqrt((x - m_x[i]) * (x - m_x[i]) + (y - m_y[i]) * (y - m_y[i])) < 5.0) { m_dx = x - m_x[i]; m_dy = y - m_y[i]; m_idx = i; break; } } if (i == 3) { if (AggMath.point_in_triangle(m_x[0], m_y[0], m_x[1], m_y[1], m_x[2], m_y[2], x, y)) { m_dx = x - m_x[0]; m_dy = y - m_y[0]; m_idx = 3; } } }
//---------------------------------------------------------------- public void Begin(double x, double y, int len) { // Calculate transformed coordinates at x1,y1 double xt = x; double yt = y; m_trans_dir.Transform(ref xt, ref yt); int x1 = AggMath.iround(xt * SUBPIXEL_SCALE); int y1 = AggMath.iround(yt * SUBPIXEL_SCALE); double dx; double dy; double delta = 1 / (double)SUBPIXEL_SCALE; // Calculate scale by X at x1,y1 dx = xt + delta; dy = yt; m_trans_inv.Transform(ref dx, ref dy); dx -= x; dy -= y; int sx1 = (int)AggMath.uround(SUBPIXEL_SCALE / Math.Sqrt(dx * dx + dy * dy)) >> SUBPIXEL_SHIFT; // Calculate scale by Y at x1,y1 dx = xt; dy = yt + delta; m_trans_inv.Transform(ref dx, ref dy); dx -= x; dy -= y; int sy1 = (int)AggMath.uround(SUBPIXEL_SCALE / Math.Sqrt(dx * dx + dy * dy)) >> SUBPIXEL_SHIFT; // Calculate transformed coordinates at x2,y2 x += len; xt = x; yt = y; m_trans_dir.Transform(ref xt, ref yt); int x2 = AggMath.iround(xt * SUBPIXEL_SCALE); int y2 = AggMath.iround(yt * SUBPIXEL_SCALE); // Calculate scale by X at x2,y2 dx = xt + delta; dy = yt; m_trans_inv.Transform(ref dx, ref dy); dx -= x; dy -= y; int sx2 = (int)AggMath.uround(SUBPIXEL_SCALE / Math.Sqrt(dx * dx + dy * dy)) >> SUBPIXEL_SHIFT; // Calculate scale by Y at x2,y2 dx = xt; dy = yt + delta; m_trans_inv.Transform(ref dx, ref dy); dx -= x; dy -= y; int sy2 = (int)AggMath.uround(SUBPIXEL_SCALE / Math.Sqrt(dx * dx + dy * dy)) >> SUBPIXEL_SHIFT; // Initialize the interpolators m_coord_x = new LineInterpolatorDDA2(x1, x2, (int)len); m_coord_y = new LineInterpolatorDDA2(y1, y2, (int)len); m_scale_x = new LineInterpolatorDDA2(sx1, sx2, (int)len); m_scale_y = new LineInterpolatorDDA2(sy1, sy2, (int)len); }
public override void ToPix(ref Color c) { c = new Color(c.A, (byte)AggMath.uround(r), c.G, c.B ); }
public PrebuiltGammaTable(IGammaFunction gamma_function) { for (int i = ScanlineRasterizer.AA_SCALE - 1; i >= 0; --i) { _gammaLut[i] = AggMath.uround( gamma_function.GetGamma((float)(i) / ScanlineRasterizer.AA_MASK) * ScanlineRasterizer.AA_MASK); } }
//bool AutoClose //{ // get { return m_auto_close; } // set { this.m_auto_close = value; } //} //-------------------------------------------------------------------- public void ResetGamma(IGammaFunction gamma_function) { for (int i = AA_SCALE - 1; i >= 0; --i) { m_gammaLut[i] = AggMath.uround( gamma_function.GetGamma((float)(i) / AA_MASK) * AA_MASK); } }
static GlyphMeshStore() { s_flipY = AffineMat.Iden(); s_flipY.Scale(1, -1); // s_slantHorizontal = AffineMat.Iden(); s_slantHorizontal.Skew(AggMath.deg2rad(-15), 0); }
public override void ToPix(ref Color c) { c = new Color( (byte)AggMath.uround(a), (byte)AggMath.uround(r), (byte)AggMath.uround(g), (byte)AggMath.uround(b) ); }
public DistanceInterpolator1(int x1, int y1, int x2, int y2, int x, int y) { _dx = (x2 - x1); _dy = (y2 - y1); _dist = (AggMath.iround((double)(x + LineAA.SUBPIXEL_SCALE / 2 - x2) * (double)(_dy) - (double)(y + LineAA.SUBPIXEL_SCALE / 2 - y2) * (double)(_dx))); _dx <<= LineAA.SUBPIXEL_SHIFT; _dy <<= LineAA.SUBPIXEL_SHIFT; }
//--------------------------------------------------------------------- public int Calculate(int x, int y, int d) { double dx = x - m_fx; double dy = y - m_fy; double d2 = dx * m_fy - dy * m_fx; double d3 = m_r2 * (dx * dx + dy * dy) - d2 * d2; return(AggMath.iround((dx * m_fx + dy * m_fy + System.Math.Sqrt(System.Math.Abs(d3))) * m_mul)); }
static LineProfileAnitAlias() { //GammaNone => just return i*** s_gamma_none = new byte[AA_SCALE]; for (int i = AA_SCALE - 1; i >= 0; --i) { s_gamma_none[i] = (byte)(AggMath.uround(((float)(i) / AA_MASK) * AA_MASK)); } }
void ISpanGenerator.Prepare() { _y2 = (int)_c1.y; _swap = AggMath.Cross(_c0.x, _c0.y, _c2.x, _c2.y, _c1.x, _c1.y) < 0.0; _rgba1.Init(_c0, _c2); _rgba2.Init(_c0, _c1); _rgba3.Init(_c1, _c2); }
public bool IsEqual(VertexDistance val) { bool ret = (dist = AggMath.calc_distance(x, y, val.x, val.y)) > AggMath.VERTEX_DISTANCE_EPSILON; if (!ret) { dist = 1.0 / AggMath.VERTEX_DISTANCE_EPSILON; } return(ret); }
public override void Line3(LineParameters lp, int sx, int sy, int ex, int ey) { if (doClipping) { int x1 = lp.x1; int y1 = lp.y1; int x2 = lp.x2; int y2 = lp.y2; int flags = ClipLiangBarsky.ClipLineSegment(ref x1, ref y1, ref x2, ref y2, clippingRectangle); if ((flags & 4) == 0) { if (flags != 0) { LineParameters lp2 = new LineParameters(x1, y1, x2, y2, AggBasics.uround(AggMath.calc_distance(x1, y1, x2, y2))); if ((flags & 1) != 0) { sx = x1 + (y2 - y1); sy = y1 - (x2 - x1); } else { while (Math.Abs(sx - lp.x1) + Math.Abs(sy - lp.y1) > lp2.len) { sx = (lp.x1 + sx) >> 1; sy = (lp.y1 + sy) >> 1; } } if ((flags & 2) != 0) { ex = x2 + (y2 - y1); ey = y2 - (x2 - x1); } else { while (Math.Abs(ex - lp.x2) + Math.Abs(ey - lp.y2) > lp2.len) { ex = (lp.x2 + ex) >> 1; ey = (lp.y2 + ey) >> 1; } } Line3NoClip(lp2, sx, sy, ex, ey); } else { Line3NoClip(lp, sx, sy, ex, ey); } } } else { Line3NoClip(lp, sx, sy, ex, ey); } }
static PreBuiltLineAAGammaTable() { { byte[] gammaValues = new byte[LineProfileAnitAlias.AA_SCALE]; for (int i = LineProfileAnitAlias.AA_SCALE - 1; i >= 0; --i) { gammaValues[i] = (byte)(AggMath.uround(((float)(i) / LineProfileAnitAlias.AA_MASK) * LineProfileAnitAlias.AA_MASK)); } None = new PreBuiltLineAAGammaTable(gammaValues); } }
void SetGamma(float g) { _gamma = g; float inv_g = (float)(1.0 / g); for (int i = GAMMA_SIZE - 1; i >= 0; --i) { _dir_gamma[i] = (byte)AggMath.uround(Math.Pow(i / (float)GAMMA_MASK, _gamma) * (float)GAMMA_MASK); _inv_gamma[i] = (byte)AggMath.uround(Math.Pow(i / (float)GAMMA_MASK, inv_g) * (float)GAMMA_MASK); } }
//-------------------------------------------------------------------- // This function normalizes integer values and corrects the rounding // errors. It doesn't do anything with the source floating point values // (m_weight_array_dbl), it corrects only integers according to the rule // of 1.0 which means that any sum of pixel weights must be equal to 1.0. // So, the filter function must produce a graph of the proper shape. //-------------------------------------------------------------------- void Normalize() { int i; int flip = 1; for (i = 0; i < (int)ImgSubPixConst.SCALE; i++) { for (; ;) { int sum = 0; int j; for (j = 0; j < _diameter; j++) { sum += _weight_array[j * (int)ImgSubPixConst.SCALE + i]; } if (sum == (int)ImgFilterConst.SCALE) { break; } double k = (double)((int)ImgFilterConst.SCALE) / (double)(sum); sum = 0; for (j = 0; j < _diameter; j++) { sum += _weight_array[j * (int)ImgSubPixConst.SCALE + i] = (int)AggMath.iround(_weight_array[j * (int)ImgSubPixConst.SCALE + i] * k); } sum -= (int)ImgFilterConst.SCALE; int inc = (sum > 0) ? -1 : 1; for (j = 0; j < _diameter && sum != 0; j++) { flip ^= 1; int idx = flip != 0 ? _diameter / 2 + j / 2 : _diameter / 2 - j / 2; int v = _weight_array[idx * (int)ImgSubPixConst.SCALE + i]; if (v < (int)ImgFilterConst.SCALE) { _weight_array[idx * (int)ImgSubPixConst.SCALE + i] += (int)inc; sum += inc; } } } } int pivot = _diameter << (ImgSubPixConst.SHIFT - 1); for (i = 0; i < pivot; i++) { _weight_array[pivot + i] = _weight_array[pivot - i]; } int end = (Diameter << ImgSubPixConst.SHIFT) - 1; _weight_array[0] = _weight_array[end]; }
public bool IsDiff(LineAAVertex val) { //*** NEED 64 bits long long dx = val.x - x; long dy = val.y - y; if ((dx + dy) == 0) { return(false); } return((len = AggMath.uround(Math.Sqrt(dx * dx + dy * dy))) > SIGDIFF); }
public override void ToPix(ref Color c) { //c.red = (byte)AggMath.uround(r); //c.green = (byte)AggMath.uround(g); //c.blue = (byte)AggMath.uround(b); c = new Color(c.A, (byte)AggMath.uround(r), (byte)AggMath.uround(g), (byte)AggMath.uround(b) ); }