public LineInterpolatorAABase(OutlineRenderer ren, LineParameters lp) { m_lp = lp; m_li = new LineInterpolatorDDA2(lp.vertical ? LineAA.DblHr(lp.x2 - lp.x1) : LineAA.DblHr(lp.y2 - lp.y1), lp.vertical ? Math.Abs(lp.y2 - lp.y1) : Math.Abs(lp.x2 - lp.x1) + 1); m_ren = ren; m_len = ((lp.vertical == (lp.inc > 0)) ? -lp.len : lp.len); m_x = (lp.x1 >> LineAA.SUBPIXEL_SHIFT); m_y = (lp.y1 >> LineAA.SUBPIXEL_SHIFT); m_old_x = (m_x); m_old_y = (m_y); m_count = ((lp.vertical ? Math.Abs((lp.y2 >> LineAA.SUBPIXEL_SHIFT) - m_y) : Math.Abs((lp.x2 >> LineAA.SUBPIXEL_SHIFT) - m_x))); m_width = (ren.SubPixelWidth); //m_max_extent(m_width >> (line_subpixel_shift - 2)); m_max_extent = ((m_width + LineAA.SUBPIXEL_MARK) >> LineAA.SUBPIXEL_SHIFT); m_step = 0; LineInterpolatorDDA2 li = new LineInterpolatorDDA2(0, lp.vertical ? (lp.dy << LineAA.SUBPIXEL_SHIFT) : (lp.dx << LineAA.SUBPIXEL_SHIFT), lp.len); int i; int stop = m_width + LineAA.SUBPIXEL_SCALE * 2; for (i = 0; i < MAX_HALF_WIDTH; ++i) { m_dist[i] = li.Y; if (m_dist[i] >= stop) break; li.Next(); } m_dist[i++] = 0x7FFF0000; }
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 = AggBasics.iround(tx); y = AggBasics.iround(ty); }
//--------------------------------------------------------------------- public LineInterpolatorAA2(OutlineRenderer ren, LineParameters lp, int ex, int ey) : base(ren, lp) { m_di = new DistanceInterpolator2(lp.x1, lp.y1, lp.x2, lp.y2, ex, ey, lp.x1 & ~LineAA.SUBPIXEL_MARK, lp.y1 & ~LineAA.SUBPIXEL_MARK, 0); base.m_li.adjust_forward(); base.m_step -= base.m_max_extent; }
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); } }
/// <summary> /// fix_degeneration_bisectrix_start /// </summary> /// <param name="lp"></param> /// <param name="x"></param> /// <param name="y"></param> public static void FixDegenBisectrixStart(LineParameters lp, ref int x, ref int y) { int d = AggBasics.iround(((double)(x - lp.x2) * (double)(lp.y2 - lp.y1) - (double)(y - lp.y2) * (double)(lp.x2 - lp.x1)) / lp.len); if (d < SUBPIXEL_SCALE / 2) { x = lp.x1 + (lp.y2 - lp.y1); y = lp.y1 - (lp.x2 - lp.x1); } }
public LineInterpolatorAA2( OutlineRenderer ren, LineParameters lp, int ex, int ey) { this._ren = ren; _aa_data = new Lines.LineInterpolatorAAData(ren, lp); _m_di = new DistanceInterpolator2(lp.x1, lp.y1, lp.x2, lp.y2, ex, ey, lp.x1 & ~LineAA.SUBPIXEL_MARK, lp.y1 & ~LineAA.SUBPIXEL_MARK, 0); _aa_data.m_li.adjust_forward(); _aa_data.m_step -= _aa_data.m_max_extent; }
void Line0NoClip(LineParameters lp) { if (lp.len > LineAA.MAX_LENGTH) { LineParameters lp1, lp2; lp.Divide(out lp1, out lp2); Line0NoClip(lp1); Line0NoClip(lp2); return; } LineInterpolatorAA0 li = new LineInterpolatorAA0(this, lp); li.Loop(); }
void Line1NoClip(LineParameters lp, int sx, int sy) { if (lp.len > LineAA.MAX_LENGTH) { LineParameters lp1, lp2; lp.Divide(out lp1, out lp2); Line1NoClip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1); Line1NoClip(lp2, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1)); return; } LineAA.FixDegenBisectrixStart(lp, ref sx, ref sy); LineInterpolatorAA1 li = new LineInterpolatorAA1(this, lp, sx, sy); li.Loop(); }
void Line2NoClip(LineParameters lp, int ex, int ey) { if (lp.len > LineAA.MAX_LENGTH) { LineParameters lp1, lp2; lp.Divide(out lp1, out lp2); Line2NoClip(lp1, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1)); Line2NoClip(lp2, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1); return; } LineAA.FixDegenBisectrixEnd(lp, ref ex, ref ey); LineInterpolatorAA2 li = new LineInterpolatorAA2(this, lp, ex, ey); li.Loop(); }
void Line3NoClip(LineParameters lp, int sx, int sy, int ex, int ey) { if (lp.len > LineAA.MAX_LENGTH) { LineParameters lp1, lp2; lp.Divide(out lp1, out lp2); int mx = lp1.x2 + (lp1.y2 - lp1.y1); int my = lp1.y2 - (lp1.x2 - lp1.x1); Line3NoClip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1, mx, my); Line3NoClip(lp2, mx, my, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1); return; } LineAA.FixDegenBisectrixStart(lp, ref sx, ref sy); LineAA.FixDegenBisectrixEnd(lp, ref ex, ref ey); LineInterpolatorAA3 li = new LineInterpolatorAA3(this, lp, sx, sy, ex, ey); li.Loop(); }
//--------------------------------------------------------------------- public void Divide(out LineParameters lp1, out LineParameters lp2) { int xmid = (x1 + x2) >> 1; int ymid = (y1 + y2) >> 1; int len2 = len >> 1; //lp1 = this; // it is a struct so this is a copy //lp2 = this; // it is a struct so this is a copy lp1 = new LineParameters(this.x1, this.y1, this.x2, this.y2, this.len); lp2 = new LineParameters(this.x1, this.y1, this.x2, this.y2, this.len); lp1.x2 = xmid; lp1.y2 = ymid; lp1.len = len2; lp1.dx = Math.Abs(lp1.x2 - lp1.x1); lp1.dy = Math.Abs(lp1.y2 - lp1.y1); lp2.x1 = xmid; lp2.y1 = ymid; lp2.len = len2; lp2.dx = Math.Abs(lp2.x2 - lp2.x1); lp2.dy = Math.Abs(lp2.y2 - lp2.y1); }
public LineInterpolatorAAData(OutlineRenderer ren, LineParameters lp) { m_dist = new int[MAX_HALF_WIDTH + 1]; m_covers = new byte[MAX_HALF_WIDTH * 2 + 4]; m_lp = lp; m_li = new LineInterpolatorDDA2(lp.vertical ? LineAA.DblHr(lp.x2 - lp.x1) : LineAA.DblHr(lp.y2 - lp.y1), lp.vertical ? Math.Abs(lp.y2 - lp.y1) : Math.Abs(lp.x2 - lp.x1) + 1); m_len = ((lp.vertical == (lp.inc > 0)) ? -lp.len : lp.len); m_x = (lp.x1 >> LineAA.SUBPIXEL_SHIFT); m_y = (lp.y1 >> LineAA.SUBPIXEL_SHIFT); m_old_x = (m_x); m_old_y = (m_y); m_count = ((lp.vertical ? Math.Abs((lp.y2 >> LineAA.SUBPIXEL_SHIFT) - m_y) : Math.Abs((lp.x2 >> LineAA.SUBPIXEL_SHIFT) - m_x))); m_width = (ren.SubPixelWidth); //m_max_extent(m_width >> (line_subpixel_shift - 2)); m_max_extent = ((m_width + LineAA.SUBPIXEL_MARK) >> LineAA.SUBPIXEL_SHIFT); m_step = 0; LineInterpolatorDDA2 li = new LineInterpolatorDDA2(0, lp.vertical ? (lp.dy << LineAA.SUBPIXEL_SHIFT) : (lp.dx << LineAA.SUBPIXEL_SHIFT), lp.len); int i; int stop = m_width + LineAA.SUBPIXEL_SCALE * 2; for (i = 0; i < MAX_HALF_WIDTH; ++i) { m_dist[i] = li.Y; if (m_dist[i] >= stop) { break; } li.Next(); } m_dist[i++] = 0x7FFF0000; }
public abstract void Line0(LineParameters lp);
public override void Line0(LineParameters lp) { }
public override void Line2(LineParameters lp, int ex, int ey) { }
public void Line3NoClip(LineParameters lp, int sx, int sy, int ex, int ey) { throw new NotImplementedException(); /* if(lp.len > LineAABasics.line_max_length) { line_parameters lp1, lp2; lp.divide(lp1, lp2); int mx = lp1.x2 + (lp1.y2 - lp1.y1); int my = lp1.y2 - (lp1.x2 - lp1.x1); line3_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1, mx, my); line3_no_clip(lp2, mx, my, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1); return; } LineAABasics.fix_degenerate_bisectrix_start(lp, ref sx, ref sy); LineAABasics.fix_degenerate_bisectrix_end(lp, ref ex, ref ey); line_interpolator_image li = new line_interpolator_image(this, lp, sx, sy, ex, ey, m_start, m_scale_x); if(li.vertical()) { while(li.step_ver()); } else { while(li.step_hor()); } m_start += uround(lp.len / m_scale_x); */ }
void Line1NoClip(LineParameters lp, int sx, int sy) { if (lp.len > LineAA.MAX_LENGTH) { LineParameters lp1, lp2; lp.Divide(out lp1, out lp2); Line1NoClip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1); Line1NoClip(lp2, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1)); return; } LineAA.FixDegenBisectrixStart(lp, ref sx, ref sy); LineInterpolatorAA1 li = new LineInterpolatorAA1(this, lp, sx, sy); if (li.IsVertical) { while (li.StepV()) ; } else { while (li.StepH()) ; } }
void Line0NoClip(LineParameters lp) { if (lp.len > LineAA.MAX_LENGTH) { LineParameters lp1, lp2; lp.Divide(out lp1, out lp2); Line0NoClip(lp1); Line0NoClip(lp2); return; } LineInterpolatorAA0 li = new LineInterpolatorAA0(this, lp); if (li.Count != 0) { if (li.IsVertical) { while (li.StepV()) ; } else { while (li.StepH()) ; } } }
void Line3NoClip(LineParameters lp, int sx, int sy, int ex, int ey) { if (lp.len > LineAA.MAX_LENGTH) { LineParameters lp1, lp2; lp.Divide(out lp1, out lp2); int mx = lp1.x2 + (lp1.y2 - lp1.y1); int my = lp1.y2 - (lp1.x2 - lp1.x1); Line3NoClip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1, mx, my); Line3NoClip(lp2, mx, my, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1); return; } LineAA.FixDegenBisectrixStart(lp, ref sx, ref sy); LineAA.FixDegenBisectrixEnd(lp, ref ex, ref ey); LineInterpolatorAA3 li = new LineInterpolatorAA3(this, lp, sx, sy, ex, ey); if (li.IsVertical) { while (li.StepV()) ; } else { while (li.StepH()) ; } }
void Draw(ref DrawVarsPart0 dv, ref DrawVarsPart1 dv1, ref DrawVarsPart2 dv2, ref LineParameters curr, ref LineParameters next, int start, int end) { int i; for (i = start; i < end; i++) { if (m_line_join == OutlineJoin.Round) { dv2.xb1 = curr.x1 + (curr.y2 - curr.y1); dv2.yb1 = curr.y1 - (curr.x2 - curr.x1); dv2.xb2 = curr.x2 + (curr.y2 - curr.y1); dv2.yb2 = curr.y2 - (curr.x2 - curr.x1); } switch (dv.flags) { case 0: m_ren.Line3(curr, dv2.xb1, dv2.yb1, dv2.xb2, dv2.yb2); break; case 1: m_ren.Line2(curr, dv2.xb2, dv2.yb2); break; case 2: m_ren.Line1(curr, dv2.xb1, dv2.yb1); break; case 3: m_ren.Line0(curr); break; } if (m_line_join == OutlineJoin.Round && (dv.flags & 2) == 0) { m_ren.Pie(curr.x2, curr.y2, curr.x2 + (curr.y2 - curr.y1), curr.y2 - (curr.x2 - curr.x1), curr.x2 + (next.y2 - next.y1), curr.y2 - (next.x2 - next.x1)); } dv1.x1 = dv1.x2; dv1.y1 = dv1.y2; dv.lcurr = dv.lnext; dv.lnext = m_src_vertices[dv.idx].len; ++dv.idx; if (dv.idx >= m_src_vertices.Count) dv.idx = 0; dv1.x2 = m_src_vertices[dv.idx].x; dv1.y2 = m_src_vertices[dv.idx].y; curr = next; next = new LineParameters(dv1.x1, dv1.y1, dv1.x2, dv1.y2, dv.lnext); dv2.xb1 = dv2.xb2; dv2.yb1 = dv2.yb2; switch (m_line_join) { case OutlineJoin.NoJoin: dv.flags = 3; break; case OutlineJoin.Mitter: dv.flags >>= 1; dv.flags |= (curr.DiagonalQuadrant == next.DiagonalQuadrant ? 1 : 0); if ((dv.flags & 2) == 0) { LineAA.Bisectrix(curr, next, out dv2.xb2, out dv2.yb2); } break; case OutlineJoin.Round: dv.flags >>= 1; dv.flags |= (((curr.DiagonalQuadrant == next.DiagonalQuadrant) ? 1 : 0) << 1); break; case OutlineJoin.AccurateJoin: dv.flags = 0; LineAA.Bisectrix(curr, next, out dv2.xb2, out dv2.yb2); break; } } }
//--------------------------------------------------------------------- public bool IsSameDiagonalQuadrant(LineParameters lp) { return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant]; }
//--------------------------------------------------------------------- public LineInterpolatorAA3(OutlineRenderer ren, LineParameters lp, int sx, int sy, int ex, int ey) : base(ren, lp) { m_di = new DistanceInterpolator3(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, lp.x1 & ~LineAA.SUBPIXEL_MARK, lp.y1 & ~LineAA.SUBPIXEL_MARK); int dist1_start; int dist2_start; int npix = 1; if (lp.vertical) { do { base.m_li.Prev(); base.m_y -= lp.inc; base.m_x = (base.m_lp.x1 + base.m_li.Y) >> LineAA.SUBPIXEL_SHIFT; if (lp.inc > 0) m_di.DecY(base.m_x - base.m_old_x); else m_di.IncY(base.m_x - base.m_old_x); base.m_old_x = base.m_x; dist1_start = dist2_start = m_di.dist_start; int dx = 0; if (dist1_start < 0) ++npix; do { dist1_start += m_di.DyStart; dist2_start -= m_di.DyStart; if (dist1_start < 0) ++npix; if (dist2_start < 0) ++npix; ++dx; } while (base.m_dist[dx] <= base.m_width); if (npix == 0) break; npix = 0; } while (--base.m_step >= -base.m_max_extent); } else { do { base.m_li.Prev(); base.m_x -= lp.inc; base.m_y = (base.m_lp.y1 + base.m_li.Y) >> LineAA.SUBPIXEL_SHIFT; if (lp.inc > 0) m_di.DecX(base.m_y - base.m_old_y); else m_di.IncX(base.m_y - base.m_old_y); base.m_old_y = base.m_y; dist1_start = dist2_start = m_di.dist_start; int dy = 0; if (dist1_start < 0) ++npix; do { dist1_start -= m_di.DxStart; dist2_start += m_di.DxStart; if (dist1_start < 0) ++npix; if (dist2_start < 0) ++npix; ++dy; } while (base.m_dist[dy] <= base.m_width); if (npix == 0) break; npix = 0; } while (--base.m_step >= -base.m_max_extent); } base.m_li.adjust_forward(); base.m_step -= base.m_max_extent; }
public void Render(bool close_polygon) { m_src_vertices.Close(close_polygon); DrawVarsPart0 dv = new DrawVarsPart0(); DrawVarsPart1 dv1 = new DrawVarsPart1(); DrawVarsPart2 dv2 = new DrawVarsPart2(); LineAAVertex v; int x1; int y1; int x2; int y2; int lprev; LineParameters curr = null; LineParameters next = null; if (close_polygon) { if (m_src_vertices.Count >= 3) { dv.idx = 2; v = m_src_vertices[m_src_vertices.Count - 1]; x1 = v.x; y1 = v.y; lprev = v.len; v = m_src_vertices[0]; x2 = v.x; y2 = v.y; dv.lcurr = v.len; LineParameters prev = new LineParameters(x1, y1, x2, y2, lprev); v = m_src_vertices[1]; dv1.x1 = v.x; dv1.y1 = v.y; dv.lnext = v.len; curr = new LineParameters(x2, y2, dv1.x1, dv1.y1, dv.lcurr); v = m_src_vertices[dv.idx]; dv1.x2 = v.x; dv1.y2 = v.y; next = new LineParameters(dv1.x1, dv1.y1, dv1.x2, dv1.y2, dv.lnext); dv2.xb1 = 0; dv2.yb1 = 0; dv2.xb2 = 0; dv2.yb2 = 0; switch (m_line_join) { case OutlineJoin.NoJoin: dv.flags = 3; break; case OutlineJoin.Mitter: case OutlineJoin.Round: dv.flags = (prev.DiagonalQuadrant == curr.DiagonalQuadrant ? 1 : 0) | ((curr.DiagonalQuadrant == next.DiagonalQuadrant ? 1 : 0) << 1); break; case OutlineJoin.AccurateJoin: dv.flags = 0; break; } if ((dv.flags & 1) == 0 && m_line_join != OutlineJoin.Round) { LineAA.Bisectrix(prev, curr, out dv2.xb1, out dv2.yb1); } if ((dv.flags & 2) == 0 && m_line_join != OutlineJoin.Round) { LineAA.Bisectrix(curr, next, out dv2.xb2, out dv2.yb2); } Draw(ref dv, ref dv1, ref dv2, ref curr, ref next, 0, m_src_vertices.Count); } } else { switch (m_src_vertices.Count) { case 0: case 1: break; case 2: { v = m_src_vertices[0]; x1 = v.x; y1 = v.y; lprev = v.len; v = m_src_vertices[1]; x2 = v.x; y2 = v.y; LineParameters lp = new LineParameters(x1, y1, x2, y2, lprev); if (m_round_cap) { m_ren.SemiDot(CompareDistStart, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); } m_ren.Line3(lp, x1 + (y2 - y1), y1 - (x2 - x1), x2 + (y2 - y1), y2 - (x2 - x1)); if (m_round_cap) { m_ren.SemiDot(CompareDistEnd, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1)); } } break; case 3: { int x3, y3; int lnext; v = m_src_vertices[0]; x1 = v.x; y1 = v.y; lprev = v.len; v = m_src_vertices[1]; x2 = v.x; y2 = v.y; lnext = v.len; v = m_src_vertices[2]; x3 = v.x; y3 = v.y; LineParameters lp1 = new LineParameters(x1, y1, x2, y2, lprev); LineParameters lp2 = new LineParameters(x2, y2, x3, y3, lnext); if (m_round_cap) { m_ren.SemiDot(CompareDistStart, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); } if (m_line_join == OutlineJoin.Round) { m_ren.Line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), x2 + (y2 - y1), y2 - (x2 - x1)); m_ren.Pie(x2, y2, x2 + (y2 - y1), y2 - (x2 - x1), x2 + (y3 - y2), y2 - (x3 - x2)); m_ren.Line3(lp2, x2 + (y3 - y2), y2 - (x3 - x2), x3 + (y3 - y2), y3 - (x3 - x2)); } else { LineAA.Bisectrix(lp1, lp2, out dv2.xb1, out dv2.yb1); m_ren.Line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), dv2.xb1, dv2.yb1); m_ren.Line3(lp2, dv2.xb1, dv2.yb1, x3 + (y3 - y2), y3 - (x3 - x2)); } if (m_round_cap) { m_ren.SemiDot(CompareDistEnd, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2)); } } break; default: { dv.idx = 3; v = m_src_vertices[0]; x1 = v.x; y1 = v.y; lprev = v.len; v = m_src_vertices[1]; x2 = v.x; y2 = v.y; dv.lcurr = v.len; LineParameters prev = new LineParameters(x1, y1, x2, y2, lprev); v = m_src_vertices[2]; dv1.x1 = v.x; dv1.y1 = v.y; dv.lnext = v.len; curr = new LineParameters(x2, y2, dv1.x1, dv1.y1, dv.lcurr); v = m_src_vertices[dv.idx]; dv1.x2 = v.x; dv1.y2 = v.y; next = new LineParameters(dv1.x1, dv1.y1, dv1.x2, dv1.y2, dv.lnext); dv2.xb1 = 0; dv2.yb1 = 0; dv2.xb2 = 0; dv2.yb2 = 0; switch (m_line_join) { case OutlineJoin.NoJoin: dv.flags = 3; break; case OutlineJoin.Mitter: case OutlineJoin.Round: dv.flags = (prev.DiagonalQuadrant == curr.DiagonalQuadrant ? 1 : 0) | ((curr.DiagonalQuadrant == next.DiagonalQuadrant ? 1 : 0) << 1); break; case OutlineJoin.AccurateJoin: dv.flags = 0; break; } if (m_round_cap) { m_ren.SemiDot(CompareDistStart, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); } if ((dv.flags & 1) == 0) { if (m_line_join == OutlineJoin.Round) { m_ren.Line3(prev, x1 + (y2 - y1), y1 - (x2 - x1), x2 + (y2 - y1), y2 - (x2 - x1)); m_ren.Pie(prev.x2, prev.y2, x2 + (y2 - y1), y2 - (x2 - x1), curr.x1 + (curr.y2 - curr.y1), curr.y1 - (curr.x2 - curr.x1)); } else { LineAA.Bisectrix(prev, curr, out dv2.xb1, out dv2.yb1); m_ren.Line3(prev, x1 + (y2 - y1), y1 - (x2 - x1), dv2.xb1, dv2.yb1); } } else { m_ren.Line1(prev, x1 + (y2 - y1), y1 - (x2 - x1)); } if ((dv.flags & 2) == 0 && m_line_join != OutlineJoin.Round) { LineAA.Bisectrix(curr, next, out dv2.xb2, out dv2.yb2); } Draw(ref dv, ref dv1, ref dv2, ref curr, ref next, 1, m_src_vertices.Count - 2); if ((dv.flags & 1) == 0) { if (m_line_join == OutlineJoin.Round) { m_ren.Line3(curr, curr.x1 + (curr.y2 - curr.y1), curr.y1 - (curr.x2 - curr.x1), curr.x2 + (curr.y2 - curr.y1), curr.y2 - (curr.x2 - curr.x1)); } else { m_ren.Line3(curr, dv2.xb1, dv2.yb1, curr.x2 + (curr.y2 - curr.y1), curr.y2 - (curr.x2 - curr.x1)); } } else { m_ren.Line2(curr, curr.x2 + (curr.y2 - curr.y1), curr.y2 - (curr.x2 - curr.x1)); } if (m_round_cap) { m_ren.SemiDot(CompareDistEnd, curr.x2, curr.y2, curr.x2 + (curr.y2 - curr.y1), curr.y2 - (curr.x2 - curr.x1)); } } break; } } m_src_vertices.Clear(); }
public abstract void Line3(LineParameters lp, int sx, int sy, int ex, int ey);
public abstract void Line2(LineParameters lp, int ex, int ey);
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); } }
void Draw(ref DrawVarsPart0 dv, ref DrawVarsPart1 dv1, ref DrawVarsPart2 dv2, ref LineParameters curr, ref LineParameters next, int start, int end) { int i; for (i = start; i < end; i++) { if (m_line_join == OutlineJoin.Round) { dv2.xb1 = curr.x1 + (curr.y2 - curr.y1); dv2.yb1 = curr.y1 - (curr.x2 - curr.x1); dv2.xb2 = curr.x2 + (curr.y2 - curr.y1); dv2.yb2 = curr.y2 - (curr.x2 - curr.x1); } switch (dv.flags) { case 0: m_ren.Line3(curr, dv2.xb1, dv2.yb1, dv2.xb2, dv2.yb2); break; case 1: m_ren.Line2(curr, dv2.xb2, dv2.yb2); break; case 2: m_ren.Line1(curr, dv2.xb1, dv2.yb1); break; case 3: m_ren.Line0(curr); break; } if (m_line_join == OutlineJoin.Round && (dv.flags & 2) == 0) { m_ren.Pie(curr.x2, curr.y2, curr.x2 + (curr.y2 - curr.y1), curr.y2 - (curr.x2 - curr.x1), curr.x2 + (next.y2 - next.y1), curr.y2 - (next.x2 - next.x1)); } dv1.x1 = dv1.x2; dv1.y1 = dv1.y2; dv.lcurr = dv.lnext; dv.lnext = m_src_vertices[dv.idx].len; ++dv.idx; if (dv.idx >= m_src_vertices.Count) { dv.idx = 0; } dv1.x2 = m_src_vertices[dv.idx].x; dv1.y2 = m_src_vertices[dv.idx].y; curr = next; next = new LineParameters(dv1.x1, dv1.y1, dv1.x2, dv1.y2, dv.lnext); dv2.xb1 = dv2.xb2; dv2.yb1 = dv2.yb2; switch (m_line_join) { case OutlineJoin.NoJoin: dv.flags = 3; break; case OutlineJoin.Mitter: dv.flags >>= 1; dv.flags |= (curr.DiagonalQuadrant == next.DiagonalQuadrant ? 1 : 0); if ((dv.flags & 2) == 0) { LineAA.Bisectrix(curr, next, out dv2.xb2, out dv2.yb2); } break; case OutlineJoin.Round: dv.flags >>= 1; dv.flags |= (((curr.DiagonalQuadrant == next.DiagonalQuadrant) ? 1 : 0) << 1); break; case OutlineJoin.AccurateJoin: dv.flags = 0; LineAA.Bisectrix(curr, next, out dv2.xb2, out dv2.yb2); break; } } }
public override void Line3(LineParameters lp, int sx, int sy, int ex, int ey) { throw new NotImplementedException(); /* if(m_clipping) { int x1 = lp.x1; int y1 = lp.y1; int x2 = lp.x2; int y2 = lp.y2; uint flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box); int start = m_start; if((flags & 4) == 0) { if(flags) { line_parameters lp2(x1, y1, x2, y2, uround(calc_distance(x1, y1, x2, y2))); if(flags & 1) { m_start += uround(calc_distance(lp.x1, lp.y1, x1, y1) / m_scale_x); 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) { 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; } } line3_no_clip(lp2, sx, sy, ex, ey); } else { line3_no_clip(lp, sx, sy, ex, ey); } } m_start = start + uround(lp.len / m_scale_x); } else { line3_no_clip(lp, sx, sy, ex, ey); } */ }
public override void Line1(LineParameters lp, int sx, int sy) { }
//--------------------------------------------------------------------- public bool IsSameDiagonalQuadrant(LineParameters lp) { return(s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant]); }
void Line2NoClip(LineParameters lp, int ex, int ey) { if (lp.len > LineAA.MAX_LENGTH) { LineParameters lp1, lp2; lp.Divide(out lp1, out lp2); Line2NoClip(lp1, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1)); Line2NoClip(lp2, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1); return; } LineAA.FixDegenBisectrixEnd(lp, ref ex, ref ey); LineInterpolatorAA2 li = new LineInterpolatorAA2(this, lp, ex, ey); if (li.IsVertical) { while (li.StepV()) ; } else { while (li.StepH()) ; } }
//--------------------------------------------------------------------- public LineInterpolatorAA3(OutlineRenderer ren, LineParameters lp, int sx, int sy, int ex, int ey) : base(ren, lp) { m_di = new DistanceInterpolator3(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, lp.x1 & ~LineAA.SUBPIXEL_MARK, lp.y1 & ~LineAA.SUBPIXEL_MARK); int dist1_start; int dist2_start; int npix = 1; if (lp.vertical) { do { base.m_li.Prev(); base.m_y -= lp.inc; base.m_x = (base.m_lp.x1 + base.m_li.Y) >> LineAA.SUBPIXEL_SHIFT; if (lp.inc > 0) { m_di.DecY(base.m_x - base.m_old_x); } else { m_di.IncY(base.m_x - base.m_old_x); } base.m_old_x = base.m_x; dist1_start = dist2_start = m_di.dist_start; int dx = 0; if (dist1_start < 0) { ++npix; } do { dist1_start += m_di.DyStart; dist2_start -= m_di.DyStart; if (dist1_start < 0) { ++npix; } if (dist2_start < 0) { ++npix; } ++dx; }while (base.m_dist[dx] <= base.m_width); if (npix == 0) { break; } npix = 0; }while (--base.m_step >= -base.m_max_extent); } else { do { base.m_li.Prev(); base.m_x -= lp.inc; base.m_y = (base.m_lp.y1 + base.m_li.Y) >> LineAA.SUBPIXEL_SHIFT; if (lp.inc > 0) { m_di.DecX(base.m_y - base.m_old_y); } else { m_di.IncX(base.m_y - base.m_old_y); } base.m_old_y = base.m_y; dist1_start = dist2_start = m_di.dist_start; int dy = 0; if (dist1_start < 0) { ++npix; } do { dist1_start -= m_di.DxStart; dist2_start += m_di.DxStart; if (dist1_start < 0) { ++npix; } if (dist2_start < 0) { ++npix; } ++dy; }while (base.m_dist[dy] <= base.m_width); if (npix == 0) { break; } npix = 0; }while (--base.m_step >= -base.m_max_extent); } base.m_li.adjust_forward(); base.m_step -= base.m_max_extent; }
public abstract void Line1(LineParameters lp, int sx, int sy);
public override void Line3(LineParameters lp, int sx, int sy, int ex, int ey) { throw new NotImplementedException(); /* * if(m_clipping) * { * int x1 = lp.x1; * int y1 = lp.y1; * int x2 = lp.x2; * int y2 = lp.y2; * uint flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box); * int start = m_start; * if((flags & 4) == 0) * { * if(flags) * { * line_parameters lp2(x1, y1, x2, y2, * uround(calc_distance(x1, y1, x2, y2))); * if(flags & 1) * { * m_start += uround(calc_distance(lp.x1, lp.y1, x1, y1) / m_scale_x); * 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) * { * 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; * } * } * line3_no_clip(lp2, sx, sy, ex, ey); * } * else * { * line3_no_clip(lp, sx, sy, ex, ey); * } * } * m_start = start + uround(lp.len / m_scale_x); * } * else * { * line3_no_clip(lp, sx, sy, ex, ey); * } */ }
//--------------------------------------------------------------------- public LineInterpolatorAA0(OutlineRenderer ren, LineParameters lp) : base(ren, lp) { m_di = new DistanceInterpolator1(lp.x1, lp.y1, lp.x2, lp.y2, lp.x1 & ~LineAA.SUBPIXEL_MARK, lp.y1 & ~LineAA.SUBPIXEL_MARK); m_li.adjust_forward(); }
public LineInterpolatorAA3(OutlineRenderer ren, LineParameters lp, int sx, int sy, int ex, int ey) { this._ren = ren; _aa_data = new Lines.LineInterpolatorAAData(ren, lp); _m_di = new DistanceInterpolator3(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, lp.x1 & ~LineAA.SUBPIXEL_MARK, lp.y1 & ~LineAA.SUBPIXEL_MARK); int dist1_start; int dist2_start; int npix = 1; if (lp.vertical) { do { _aa_data.m_li.Prev(); _aa_data.m_y -= lp.inc; _aa_data.m_x = (_aa_data.m_lp.x1 + _aa_data.m_li.Y) >> LineAA.SUBPIXEL_SHIFT; if (lp.inc > 0) { _m_di.DecY(_aa_data.m_x - _aa_data.m_old_x); } else { _m_di.IncY(_aa_data.m_x - _aa_data.m_old_x); } _aa_data.m_old_x = _aa_data.m_x; dist1_start = dist2_start = _m_di.dist_start; int dx = 0; if (dist1_start < 0) { ++npix; } do { dist1_start += _m_di.DyStart; dist2_start -= _m_di.DyStart; if (dist1_start < 0) { ++npix; } if (dist2_start < 0) { ++npix; } ++dx; }while (_aa_data.m_dist[dx] <= _aa_data.m_width); if (npix == 0) { break; } npix = 0; }while (--_aa_data.m_step >= -_aa_data.m_max_extent); } else { do { _aa_data.m_li.Prev(); _aa_data.m_x -= lp.inc; _aa_data.m_y = (_aa_data.m_lp.y1 + _aa_data.m_li.Y) >> LineAA.SUBPIXEL_SHIFT; if (lp.inc > 0) { _m_di.DecX(_aa_data.m_y - _aa_data.m_old_y); } else { _m_di.IncX(_aa_data.m_y - _aa_data.m_old_y); } _aa_data.m_old_y = _aa_data.m_y; dist1_start = dist2_start = _m_di.dist_start; int dy = 0; if (dist1_start < 0) { ++npix; } do { dist1_start -= _m_di.DxStart; dist2_start += _m_di.DxStart; if (dist1_start < 0) { ++npix; } if (dist2_start < 0) { ++npix; } ++dy; }while (_aa_data.m_dist[dy] <= _aa_data.m_width); if (npix == 0) { break; } npix = 0; }while (--_aa_data.m_step >= -_aa_data.m_max_extent); } _aa_data.m_li.adjust_forward(); _aa_data.m_step -= _aa_data.m_max_extent; }