public void CreateCap(VertexStore output, VertexDistance v0, VertexDistance v1, double len) { output.Clear(); double dx1 = (v1.y - v0.y) / len; double dy1 = (v1.x - v0.x) / len; double dx2 = 0; double dy2 = 0; dx1 *= m_width; dy1 *= m_width; if (m_line_cap != LineCap.Round) { if (m_line_cap == LineCap.Square) { dx2 = dy1 * m_width_sign; dy2 = dx1 * m_width_sign; } AddVertex(output, v0.x - dx1 - dx2, v0.y + dy1 - dy2); AddVertex(output, v0.x + dx1 - dx2, v0.y - dy1 - dy2); } else { double da = Math.Acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2; double a1; int i; int n = (int)(Math.PI / da); da = Math.PI / (n + 1); AddVertex(output, v0.x - dx1, v0.y + dy1); if (m_width_sign > 0) { a1 = Math.Atan2(dy1, -dx1); a1 += da; for (i = 0; i < n; i++) { AddVertex(output, v0.x + Math.Cos(a1) * m_width, v0.y + Math.Sin(a1) * m_width); a1 += da; } } else { a1 = Math.Atan2(-dy1, dx1); a1 -= da; for (i = 0; i < n; i++) { AddVertex(output, v0.x + Math.Cos(a1) * m_width, v0.y + Math.Sin(a1) * m_width); a1 -= da; } } AddVertex(output, v0.x + dx1, v0.y - dy1); } }
public void dbugLine(double x1, double y1, double x2, double y2, Drawing.Color color) { dbug_v1.AddMoveTo(x1, y1); dbug_v1.AddLineTo(x2, y2); //dbug_v1.AddStop(); dbugStroke.MakeVxs(dbug_v1, dbug_v2); Render(dbug_v2, color); dbug_v1.Clear(); dbug_v2.Clear(); }
static Affine BuildImageBoundsPath(int srcW, int srcH, VertexStore drawImageRectPath, AffinePlan[] affPlans) { drawImageRectPath.Clear(); drawImageRectPath.AddMoveTo(0, 0); drawImageRectPath.AddLineTo(srcW, 0); drawImageRectPath.AddLineTo(srcW, srcH); drawImageRectPath.AddLineTo(0, srcH); drawImageRectPath.AddCloseFigure(); return(Affine.NewMatix(affPlans)); }
static Affine BuildImageBoundsPath(int srcW, int srcH, AffinePlan[] affPlans, VertexStore outputDestImgRect) { outputDestImgRect.Clear(); outputDestImgRect.AddMoveTo(0, 0); outputDestImgRect.AddLineTo(srcW, 0); outputDestImgRect.AddLineTo(srcW, srcH); outputDestImgRect.AddLineTo(0, srcH); outputDestImgRect.AddCloseFigure(); return(Affine.NewMatix(affPlans)); }
Affine BuildImageBoundsPath(IImageReaderWriter sourceImage, VertexStore drawImageRectPath, AffinePlan[] affPlans) { int srcW = sourceImage.Width; int srcH = sourceImage.Height; drawImageRectPath.Clear(); drawImageRectPath.AddMoveTo(0, 0); drawImageRectPath.AddLineTo(srcW, 0); drawImageRectPath.AddLineTo(srcW, srcH); drawImageRectPath.AddLineTo(0, srcH); drawImageRectPath.AddCloseFigure(); return(Affine.NewMatix(affPlans)); }
Affine BuildImageBoundsPath(IImageReaderWriter sourceImage, VertexStore drawImageRectPath, double destX, double destY, double hotspotOffsetX, double hotSpotOffsetY, double scaleX, double scaleY, double angleRad) { AffinePlan[] plan = new AffinePlan[4]; int i = 0; if (hotspotOffsetX != 0.0f || hotSpotOffsetY != 0.0f) { plan[i] = AffinePlan.Translate(-hotspotOffsetX, -hotSpotOffsetY); i++; } if (scaleX != 1 || scaleY != 1) { plan[i] = AffinePlan.Scale(scaleX, scaleY); i++; } if (angleRad != 0) { plan[i] = AffinePlan.Rotate(angleRad); i++; } if (destX != 0 || destY != 0) { plan[i] = AffinePlan.Translate(destX, destY); i++; } int srcW = sourceImage.Width; int srcH = sourceImage.Height; drawImageRectPath.Clear(); drawImageRectPath.AddMoveTo(0, 0); drawImageRectPath.AddLineTo(srcW, 0); drawImageRectPath.AddLineTo(srcW, srcH); drawImageRectPath.AddLineTo(0, srcH); drawImageRectPath.AddCloseFigure(); return(Affine.NewMatix(plan)); }
static Affine BuildImageBoundsPath( int srcW, int srcH, double destX, double destY, VertexStore outputDestImgRect) { AffinePlan plan = new AffinePlan(); if (destX != 0 || destY != 0) { plan = AffinePlan.Translate(destX, destY); } outputDestImgRect.Clear(); outputDestImgRect.AddMoveTo(0, 0); outputDestImgRect.AddLineTo(srcW, 0); outputDestImgRect.AddLineTo(srcW, srcH); outputDestImgRect.AddLineTo(0, srcH); outputDestImgRect.AddCloseFigure(); return(Affine.NewMatix(plan)); }
static Affine BuildImageBoundsPath( int srcW, int srcH, double destX, double destY, double hotspotOffsetX, double hotSpotOffsetY, double scaleX, double scaleY, double angleRad, VertexStore outputDestImgRect) { AffinePlan[] plans = new AffinePlan[4]; int i = 0; if (hotspotOffsetX != 0.0f || hotSpotOffsetY != 0.0f) { plans[i] = AffinePlan.Translate(-hotspotOffsetX, -hotSpotOffsetY); i++; } if (scaleX != 1 || scaleY != 1) { plans[i] = AffinePlan.Scale(scaleX, scaleY); i++; } if (angleRad != 0) { plans[i] = AffinePlan.Rotate(angleRad); i++; } if (destX != 0 || destY != 0) { plans[i] = AffinePlan.Translate(destX, destY); i++; } outputDestImgRect.Clear(); outputDestImgRect.AddMoveTo(0, 0); outputDestImgRect.AddLineTo(srcW, 0); outputDestImgRect.AddLineTo(srcW, srcH); outputDestImgRect.AddLineTo(0, srcH); outputDestImgRect.AddCloseFigure(); return(Affine.NewMatix(plans)); }
Affine BuildImageBoundsPath( int srcW, int srcH, VertexStore drawImageRectPath, double destX, double destY, double hotspotOffsetX, double hotSpotOffsetY, double scaleX, double scaleY, double angleRad) { AffinePlan[] plan = new AffinePlan[4]; int i = 0; if (hotspotOffsetX != 0.0f || hotSpotOffsetY != 0.0f) { plan[i] = AffinePlan.Translate(-hotspotOffsetX, -hotSpotOffsetY); i++; } if (scaleX != 1 || scaleY != 1) { plan[i] = AffinePlan.Scale(scaleX, scaleY); i++; } if (angleRad != 0) { plan[i] = AffinePlan.Rotate(angleRad); i++; } if (destX != 0 || destY != 0) { plan[i] = AffinePlan.Translate(destX, destY); i++; } drawImageRectPath.Clear(); drawImageRectPath.AddMoveTo(0, 0); drawImageRectPath.AddLineTo(srcW, 0); drawImageRectPath.AddLineTo(srcW, srcH); drawImageRectPath.AddLineTo(0, srcH); drawImageRectPath.AddCloseFigure(); return Affine.NewMatix(plan); }
Affine BuildImageBoundsPath( int srcW, int srcH, VertexStore drawImageRectPath, double destX, double destY) { AffinePlan plan = new AffinePlan(); if (destX != 0 || destY != 0) { plan = AffinePlan.Translate(destX, destY); } drawImageRectPath.Clear(); drawImageRectPath.AddMoveTo(0, 0); drawImageRectPath.AddLineTo(srcW, 0); drawImageRectPath.AddLineTo(srcW, srcH); drawImageRectPath.AddLineTo(0, srcH); drawImageRectPath.AddCloseFigure(); return(Affine.NewMatix(plan)); }
Affine BuildImageBoundsPath(IImageReaderWriter sourceImage, VertexStore drawImageRectPath, double destX, double destY) { AffinePlan plan = new AffinePlan(); if (destX != 0 || destY != 0) { plan = AffinePlan.Translate(destX, destY); } int srcW = sourceImage.Width; int srcH = sourceImage.Height; drawImageRectPath.Clear(); drawImageRectPath.AddMoveTo(0, 0); drawImageRectPath.AddLineTo(srcW, 0); drawImageRectPath.AddLineTo(srcW, srcH); drawImageRectPath.AddLineTo(0, srcH); drawImageRectPath.AddCloseFigure(); return(Affine.NewMatix(plan)); }
static Affine BuildImageBoundsPath(int srcW, int srcH, VertexStore drawImageRectPath, AffinePlan[] affPlans) { drawImageRectPath.Clear(); drawImageRectPath.AddMoveTo(0, 0); drawImageRectPath.AddLineTo(srcW, 0); drawImageRectPath.AddLineTo(srcW, srcH); drawImageRectPath.AddLineTo(0, srcH); drawImageRectPath.AddCloseFigure(); return Affine.NewMatix(affPlans); }
Affine BuildImageBoundsPath( int srcW, int srcH, VertexStore drawImageRectPath, double destX, double destY) { AffinePlan plan = new AffinePlan(); if (destX != 0 || destY != 0) { plan = AffinePlan.Translate(destX, destY); } drawImageRectPath.Clear(); drawImageRectPath.AddMoveTo(0, 0); drawImageRectPath.AddLineTo(srcW, 0); drawImageRectPath.AddLineTo(srcW, srcH); drawImageRectPath.AddLineTo(0, srcH); drawImageRectPath.AddCloseFigure(); return Affine.NewMatix(plan); }
public void CreateJoin(VertexStore output, VertexDistance v0, VertexDistance v1, VertexDistance v2, double len1, double len2) { double dx1 = m_width * (v1.y - v0.y) / len1; double dy1 = m_width * (v1.x - v0.x) / len1; double dx2 = m_width * (v2.y - v1.y) / len2; double dy2 = m_width * (v2.x - v1.x) / len2; output.Clear(); double cp = AggMath.Cross(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y); if (cp != 0 && (cp > 0) == (m_width > 0)) { // Inner join //--------------- double limit = ((len1 < len2) ? len1 : len2) / m_width_abs; if (limit < m_inner_miter_limit) { limit = m_inner_miter_limit; } switch (m_inner_join) { default: // inner_bevel AddVertex(output, v1.x + dx1, v1.y - dy1); AddVertex(output, v1.x + dx2, v1.y - dy2); break; case InnerJoin.Miter: CreateMiter(output, v0, v1, v2, dx1, dy1, dx2, dy2, LineJoin.MiterRevert, limit, 0); break; case InnerJoin.Jag: case InnerJoin.Round: cp = (dx1 - dx2) * (dx1 - dx2) + (dy1 - dy2) * (dy1 - dy2); if (cp < len1 * len1 && cp < len2 * len2) { CreateMiter(output, v0, v1, v2, dx1, dy1, dx2, dy2, LineJoin.MiterRevert, limit, 0); } else { if (m_inner_join == InnerJoin.Jag) { AddVertex(output, v1.x + dx1, v1.y - dy1); AddVertex(output, v1.x, v1.y); AddVertex(output, v1.x + dx2, v1.y - dy2); } else { AddVertex(output, v1.x + dx1, v1.y - dy1); AddVertex(output, v1.x, v1.y); CreateArc(output, v1.x, v1.y, dx2, -dy2, dx1, -dy1); AddVertex(output, v1.x, v1.y); AddVertex(output, v1.x + dx2, v1.y - dy2); } } break; } } else { // Outer join //--------------- // Calculate the distance between v1 and // the central point of the bevel line segment //--------------- double dx = (dx1 + dx2) / 2; double dy = (dy1 + dy2) / 2; double dbevel = Math.Sqrt(dx * dx + dy * dy); if (m_line_join == LineJoin.Round || m_line_join == LineJoin.Bevel) { // This is an optimization that reduces the number of points // in cases of almost collinear segments. If there's no // visible difference between bevel and miter joins we'd rather // use miter join because it adds only one point instead of two. // // Here we calculate the middle point between the bevel points // and then, the distance between v1 and this middle point. // At outer joins this distance always less than stroke width, // because it's actually the height of an isosceles triangle of // v1 and its two bevel points. If the difference between this // width and this value is small (no visible bevel) we can // add just one point. // // The constant in the expression makes the result approximately // the same as in round joins and caps. You can safely comment // out this entire "if". //------------------- if (m_approx_scale * (m_width_abs - dbevel) < m_width_eps) { if (AggMath.CalcIntersect(v0.x + dx1, v0.y - dy1, v1.x + dx1, v1.y - dy1, v1.x + dx2, v1.y - dy2, v2.x + dx2, v2.y - dy2, out dx, out dy)) { AddVertex(output, dx, dy); } else { AddVertex(output, v1.x + dx1, v1.y - dy1); } return; } } switch (m_line_join) { case LineJoin.Miter: case LineJoin.MiterRevert: case LineJoin.MiterRound: CreateMiter(output, v0, v1, v2, dx1, dy1, dx2, dy2, m_line_join, m_miter_limit, dbevel); break; case LineJoin.Round: CreateArc(output, v1.x, v1.y, dx1, -dy1, dx2, -dy2); break; default: // Bevel join AddVertex(output, v1.x + dx1, v1.y - dy1); AddVertex(output, v1.x + dx2, v1.y - dy2); break; } } }
public void CreateCap(VertexStore output, VertexDistance v0, VertexDistance v1, double len) { output.Clear(); double dx1 = (v1.y - v0.y) / len; double dy1 = (v1.x - v0.x) / len; double dx2 = 0; double dy2 = 0; dx1 *= m_width; dy1 *= m_width; if (m_line_cap != LineCap.Round) { if (m_line_cap == LineCap.Square) { dx2 = dy1 * m_width_sign; dy2 = dx1 * m_width_sign; } AddVertex(output, v0.x - dx1 - dx2, v0.y + dy1 - dy2); AddVertex(output, v0.x + dx1 - dx2, v0.y - dy1 - dy2); } else { double da = Math.Acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2; double a1; int i; int n = (int)(Math.PI / da); da = Math.PI / (n + 1); AddVertex(output, v0.x - dx1, v0.y + dy1); if (m_width_sign > 0) { a1 = Math.Atan2(dy1, -dx1); a1 += da; for (i = 0; i < n; i++) { AddVertex(output, v0.x + Math.Cos(a1) * m_width, v0.y + Math.Sin(a1) * m_width); a1 += da; } } else { a1 = Math.Atan2(-dy1, dx1); a1 -= da; for (i = 0; i < n; i++) { AddVertex(output, v0.x + Math.Cos(a1) * m_width, v0.y + Math.Sin(a1) * m_width); a1 -= da; } } AddVertex(output, v0.x + dx1, v0.y - dy1); } }
public void Release(ref VertexStore vxs) { vxs.Clear(); _stack.Push(vxs); vxs = null; }
public void Release(ref VertexStore vxs) { vxs.Clear(); _stack.Push(vxs); vxs = null; }
void ReleaseVxs(VertexStore vxs) { this.myTmpImgRectVxs = vxs; vxs.Clear(); }
public void CreateJoin(VertexStore output, VertexDistance v0, VertexDistance v1, VertexDistance v2, double len1, double len2) { double dx1 = m_width * (v1.y - v0.y) / len1; double dy1 = m_width * (v1.x - v0.x) / len1; double dx2 = m_width * (v2.y - v1.y) / len2; double dy2 = m_width * (v2.x - v1.x) / len2; output.Clear(); double cp = AggMath.Cross(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y); if (cp != 0 && (cp > 0) == (m_width > 0)) { // Inner join //--------------- double limit = ((len1 < len2) ? len1 : len2) / m_width_abs; if (limit < m_inner_miter_limit) { limit = m_inner_miter_limit; } switch (m_inner_join) { default: // inner_bevel AddVertex(output, v1.x + dx1, v1.y - dy1); AddVertex(output, v1.x + dx2, v1.y - dy2); break; case InnerJoin.Miter: CreateMiter(output, v0, v1, v2, dx1, dy1, dx2, dy2, LineJoin.MiterRevert, limit, 0); break; case InnerJoin.Jag: case InnerJoin.Round: cp = (dx1 - dx2) * (dx1 - dx2) + (dy1 - dy2) * (dy1 - dy2); if (cp < len1 * len1 && cp < len2 * len2) { CreateMiter(output, v0, v1, v2, dx1, dy1, dx2, dy2, LineJoin.MiterRevert, limit, 0); } else { if (m_inner_join == InnerJoin.Jag) { AddVertex(output, v1.x + dx1, v1.y - dy1); AddVertex(output, v1.x, v1.y); AddVertex(output, v1.x + dx2, v1.y - dy2); } else { AddVertex(output, v1.x + dx1, v1.y - dy1); AddVertex(output, v1.x, v1.y); CreateArc(output, v1.x, v1.y, dx2, -dy2, dx1, -dy1); AddVertex(output, v1.x, v1.y); AddVertex(output, v1.x + dx2, v1.y - dy2); } } break; } } else { // Outer join //--------------- // Calculate the distance between v1 and // the central point of the bevel line segment //--------------- double dx = (dx1 + dx2) / 2; double dy = (dy1 + dy2) / 2; double dbevel = Math.Sqrt(dx * dx + dy * dy); if (m_line_join == LineJoin.Round || m_line_join == LineJoin.Bevel) { // This is an optimization that reduces the number of points // in cases of almost collinear segments. If there's no // visible difference between bevel and miter joins we'd rather // use miter join because it adds only one point instead of two. // // Here we calculate the middle point between the bevel points // and then, the distance between v1 and this middle point. // At outer joins this distance always less than stroke width, // because it's actually the height of an isosceles triangle of // v1 and its two bevel points. If the difference between this // width and this value is small (no visible bevel) we can // add just one point. // // The constant in the expression makes the result approximately // the same as in round joins and caps. You can safely comment // out this entire "if". //------------------- if (m_approx_scale * (m_width_abs - dbevel) < m_width_eps) { if (AggMath.CalcIntersect(v0.x + dx1, v0.y - dy1, v1.x + dx1, v1.y - dy1, v1.x + dx2, v1.y - dy2, v2.x + dx2, v2.y - dy2, out dx, out dy)) { AddVertex(output, dx, dy); } else { AddVertex(output, v1.x + dx1, v1.y - dy1); } return; } } switch (m_line_join) { case LineJoin.Miter: case LineJoin.MiterRevert: case LineJoin.MiterRound: CreateMiter(output, v0, v1, v2, dx1, dy1, dx2, dy2, m_line_join, m_miter_limit, dbevel); break; case LineJoin.Round: CreateArc(output, v1.x, v1.y, dx1, -dy1, dx2, -dy2); break; default: // Bevel join AddVertex(output, v1.x + dx1, v1.y - dy1); AddVertex(output, v1.x + dx2, v1.y - dy2); break; } } }
public void Render(Painter p) { // if (HasBitmapSnapshot) { p.DrawImage(_backimg, X, Y); return; } PixelFarm.Agg.Transform.Affine currentTx = null; var renderState = new TempRenderState(); renderState.strokeColor = p.StrokeColor; renderState.strokeWidth = (float)p.StrokeWidth; renderState.fillColor = p.FillColor; renderState.affineTx = currentTx; //------------------ VertexStore tempVxs = p.GetTempVxsStore(); int j = _vxList.Length; for (int i = 0; i < j; ++i) { SvgPart vx = _vxList[i]; switch (vx.Kind) { case SvgRenderVxKind.BeginGroup: { //1. save current state before enter new state p.StackPushUserObject(renderState); //2. enter new px context if (vx.HasFillColor) { p.FillColor = renderState.fillColor = vx.FillColor; } if (vx.HasStrokeColor) { p.StrokeColor = renderState.strokeColor = vx.StrokeColor; } if (vx.HasStrokeWidth) { p.StrokeWidth = renderState.strokeWidth = vx.StrokeWidth; } if (vx.AffineTx != null) { //apply this to current tx if (currentTx != null) { currentTx = currentTx * vx.AffineTx; } else { currentTx = vx.AffineTx; } renderState.affineTx = currentTx; } } break; case SvgRenderVxKind.EndGroup: { //restore to prev state renderState = (TempRenderState)p.StackPopUserObject(); p.FillColor = renderState.fillColor; p.StrokeColor = renderState.strokeColor; p.StrokeWidth = renderState.strokeWidth; currentTx = renderState.affineTx; } break; case SvgRenderVxKind.Path: { VertexStore vxs = vx.GetVxs(); if (vx.HasFillColor) { //has specific fill color if (vx.FillColor.A > 0) { if (currentTx == null) { p.Fill(vxs, vx.FillColor); } else { //have some tx tempVxs.Clear(); currentTx.TransformToVxs(vxs, tempVxs); p.Fill(tempVxs, vx.FillColor); } } } else { if (p.FillColor.A > 0) { if (currentTx == null) { p.Fill(vxs); } else { //have some tx tempVxs.Clear(); currentTx.TransformToVxs(vxs, tempVxs); p.Fill(tempVxs); } } } if (p.StrokeWidth > 0) { //check if we have a stroke version of this render vx //if not then request a new one if (vx.HasStrokeColor) { //has specific stroke color p.StrokeWidth = vx.StrokeWidth; VertexStore strokeVxs = GetStrokeVxsOrCreateNew(vx, p, (float)p.StrokeWidth); if (currentTx == null) { p.Fill(strokeVxs, vx.StrokeColor); } else { //have some tx tempVxs.Clear(); currentTx.TransformToVxs(strokeVxs, tempVxs); p.Fill(tempVxs, vx.StrokeColor); } } else if (p.StrokeColor.A > 0) { VertexStore strokeVxs = GetStrokeVxsOrCreateNew(vx, p, (float)p.StrokeWidth); if (currentTx == null) { p.Fill(strokeVxs, p.StrokeColor); } else { tempVxs.Clear(); currentTx.TransformToVxs(strokeVxs, tempVxs); p.Fill(tempVxs, p.StrokeColor); } } else { } } else { if (vx.HasStrokeColor) { VertexStore strokeVxs = GetStrokeVxsOrCreateNew(vx, p, (float)p.StrokeWidth); p.Fill(strokeVxs); } else if (p.StrokeColor.A > 0) { VertexStore strokeVxs = GetStrokeVxsOrCreateNew(vx, p, (float)p.StrokeWidth); p.Fill(strokeVxs, p.StrokeColor); } } } break; } } p.ReleaseTempVxsStore(tempVxs); }