public static SvgPart TransformToNew(SvgPart originalSvgVx, PixelFarm.Agg.Transform.Affine tx) { SvgPart newSx = new SvgPart(originalSvgVx.Kind); if (originalSvgVx._vxs != null) { VertexStore vxs = new VertexStore(); tx.TransformToVxs(originalSvgVx._vxs, vxs); newSx._vxs = vxs; } if (originalSvgVx.HasFillColor) { newSx._fillColor = originalSvgVx._fillColor; } if (originalSvgVx.HasStrokeColor) { newSx.StrokeColor = originalSvgVx.StrokeColor; } if (originalSvgVx.HasStrokeWidth) { newSx.StrokeWidth = originalSvgVx.StrokeWidth; } return(newSx); }
public override void Draw(PixelFarm.Drawing.Painter p) { if (myvxs == null) { var transform = Affine.NewMatix( AffinePlan.Translate(-lionShape.Center.x, -lionShape.Center.y), AffinePlan.Scale(spriteScale, spriteScale), AffinePlan.Rotate(angle + Math.PI), AffinePlan.Skew(skewX / 1000.0, skewY / 1000.0), AffinePlan.Translate(Width / 2, Height / 2) ); //create vertextStore again from original path myvxs = new VertexStore(); transform.TransformToVxs(lionShape.Vxs, myvxs); if (AutoFlipY) { //flip the lion PixelFarm.Agg.Transform.Affine aff = PixelFarm.Agg.Transform.Affine.NewMatix( PixelFarm.Agg.Transform.AffinePlan.Scale(-1, -1), PixelFarm.Agg.Transform.AffinePlan.Translate(0, 600)); // var v2 = new VertexStore(); myvxs = transform.TransformToVxs(myvxs, v2); } } //--------------------------------------------------------------------------------------------- { int j = lionShape.NumPaths; int[] pathList = lionShape.PathIndexList; Drawing.Color[] colors = lionShape.Colors; //graphics2D.UseSubPixelRendering = true; for (int i = 0; i < j; ++i) { p.FillColor = colors[i]; p.Fill(new VertexStoreSnap(myvxs, pathList[i])); } } //test if (SharpenRadius > 0) { //p.DoFilter(new RectInt(0, p.Height, p.Width, 0), 2); //PixelFarm.Agg.Imaging.SharpenFilterARGB.Sharpen() } }
// From affine public Perspective(Affine a) { sx = a.sx; shy = a.shy; w0 = 0; shx = a.shx; sy = a.sy; w1 = 0; tx = a.tx; ty = a.ty; w2 = 1; }
// Multiply inverse of "m" by "this" and assign the result to "this" Perspective premultiply_inv(Affine m) { Perspective t = new Perspective(m); t.invert(); Set(t.multiply(this)); return this; }
//------------------------------------------------------------------------ Perspective trans_perspectivemultiply_inv(Affine m) { Affine t = m; var invert = t.CreateInvert(); return multiply(invert); }
//------------------------------------------------------------------------ Perspective multiply(Affine a) { Perspective b = new Perspective(this); sx = a.sx * b.sx + a.shx * b.shy + a.tx * b.w0; shx = a.sx * b.shx + a.shx * b.sy + a.tx * b.w1; tx = a.sx * b.tx + a.shx * b.ty + a.tx * b.w2; shy = a.shy * b.sx + a.sy * b.shy + a.ty * b.w0; sy = a.shy * b.shx + a.sy * b.sy + a.ty * b.w1; ty = a.shy * b.tx + a.sy * b.ty + a.ty * b.w2; return this; }
//--------------------------------------------------------- Operations public Perspective from_affine(Affine a) { sx = a.sx; shy = a.shy; w0 = 0; shx = a.shx; sy = a.sy; w1 = 0; tx = a.tx; ty = a.ty; w2 = 1; return this; }
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); }
/* //===============================================trans_affine_line_segment // Rotate, Scale and Translate, associating 0...dist with line segment // x1,y1,x2,y2 public static Affine NewScaling(double x, double y) { return new Affine(x, 0.0, 0.0, y, 0.0, 0.0); } public sealed class trans_affine_line_segment : Affine { public trans_affine_line_segment(double x1, double y1, double x2, double y2, double dist) { double dx = x2 - x1; double dy = y2 - y1; if (dist > 0.0) { //multiply(trans_affine_scaling(sqrt(dx * dx + dy * dy) / dist)); } //multiply(trans_affine_rotation(Math.Atan2(dy, dx))); //multiply(trans_affine_translation(x1, y1)); } }; //============================================trans_affine_reflection_unit // Reflection matrix. Reflect coordinates across the line through // the origin containing the unit vector (ux, uy). // Contributed by John Horigan public static Affine NewScaling(double x, double y) { return new Affine(x, 0.0, 0.0, y, 0.0, 0.0); } public class trans_affine_reflection_unit : Affine { public trans_affine_reflection_unit(double ux, double uy) : base(2.0 * ux * ux - 1.0, 2.0 * ux * uy, 2.0 * ux * uy, 2.0 * uy * uy - 1.0, 0.0, 0.0) { } }; //=================================================trans_affine_reflection // Reflection matrix. Reflect coordinates across the line through // the origin at the angle a or containing the non-unit vector (x, y). // Contributed by John Horigan public static Affine NewScaling(double x, double y) { return new Affine(x, 0.0, 0.0, y, 0.0, 0.0); } public sealed class trans_affine_reflection : trans_affine_reflection_unit { public trans_affine_reflection(double a) : base(Math.Cos(a), Math.Sin(a)) { } public trans_affine_reflection(double x, double y) : base(x / Math.Sqrt(x * x + y * y), y / Math.Sqrt(x * x + y * y)) { } }; */ /* // Rectangle to a parallelogram. trans_affine(double x1, double y1, double x2, double y2, double* parl) { rect_to_parl(x1, y1, x2, y2, parl); } // Parallelogram to a rectangle. trans_affine(double* parl, double x1, double y1, double x2, double y2) { parl_to_rect(parl, x1, y1, x2, y2); } // Arbitrary parallelogram transformation. trans_affine(double* src, double* dst) { parl_to_parl(src, dst); } //---------------------------------- Parellelogram transformations // transform a parallelogram to another one. Src and dst are // pointers to arrays of three points (double[6], x1,y1,...) that // identify three corners of the parallelograms assuming implicit // fourth point. The arguments are arrays of double[6] mapped // to x1,y1, x2,y2, x3,y3 where the coordinates are: // *-----------------* // / (x3,y3)/ // / / // /(x1,y1) (x2,y2)/ // *-----------------* trans_affine parl_to_parl(double* src, double* dst) { sx = src[2] - src[0]; shy = src[3] - src[1]; shx = src[4] - src[0]; sy = src[5] - src[1]; tx = src[0]; ty = src[1]; invert(); multiply(trans_affine(dst[2] - dst[0], dst[3] - dst[1], dst[4] - dst[0], dst[5] - dst[1], dst[0], dst[1])); return *this; } trans_affine rect_to_parl(double x1, double y1, double x2, double y2, double* parl) { double src[6]; src[0] = x1; src[1] = y1; src[2] = x2; src[3] = y1; src[4] = x2; src[5] = y2; parl_to_parl(src, parl); return *this; } trans_affine parl_to_rect(double* parl, double x1, double y1, double x2, double y2) { double dst[6]; dst[0] = x1; dst[1] = y1; dst[2] = x2; dst[3] = y1; dst[4] = x2; dst[5] = y2; parl_to_parl(parl, dst); return *this; } */ //------------------------------------------ Operations // Reset - load an identity matrix //public void identity() //{ // sx = sy = 1.0; // shy = shx = tx = ty = 0.0; //} //Direct transformations operations //public void translate(double x, double y) //{ // tx += x; // ty += y; //} //public void rotate(double AngleRadians) //{ // double ca = Math.Cos(AngleRadians); // double sa = Math.Sin(AngleRadians); // double t0 = sx * ca - shy * sa; // double t2 = shx * ca - sy * sa; // double t4 = tx * ca - ty * sa; // shy = sx * sa + shy * ca; // sy = shx * sa + sy * ca; // ty = tx * sa + ty * ca; // sx = t0; // shx = t2; // tx = t4; //} //public void scale(double x, double y) //{ // double mm0 = x; // Possible hint for the optimizer // double mm3 = y; // sx *= mm0; // shx *= mm0; // tx *= mm0; // shy *= mm3; // sy *= mm3; // ty *= mm3; //} //public void scale(double scaleAmount) //{ // sx *= scaleAmount; // shx *= scaleAmount; // tx *= scaleAmount; // shy *= scaleAmount; // sy *= scaleAmount; // ty *= scaleAmount; //} // Multiply matrix to another one static void MultiplyMatrix( ref double sx, ref double sy, ref double shx, ref double shy, ref double tx, ref double ty, Affine m) { double t0 = sx * m.sx + shy * m.shx; double t2 = shx * m.sx + sy * m.shx; double t4 = tx * m.sx + ty * m.shx + m.tx; shy = sx * m.shy + shy * m.sy; sy = shx * m.shy + sy * m.sy; ty = tx * m.shy + ty * m.sy + m.ty; sx = t0; shx = t2; tx = t4; }
//---------------------------------------------------------- // Identity matrix static Affine NewIdentity() { var newIden = new Affine( 1, 0, 0, 1, 0, 0); newIden.isIdenHint = true; return newIden; }
private Affine(Affine copyFrom, AffinePlan creationPlan) { //----------------------- sx = copyFrom.sx; shy = copyFrom.shy; shx = copyFrom.shx; sy = copyFrom.sy; tx = copyFrom.tx; ty = copyFrom.ty; //----------------------- switch (creationPlan.cmd) { default: { throw new NotSupportedException(); } case AffineMatrixCommand.None: break; case AffineMatrixCommand.Rotate: { double angleRad = creationPlan.x; double ca = Math.Cos(angleRad); double sa = Math.Sin(angleRad); double t0 = sx * ca - shy * sa; double t2 = shx * ca - sy * sa; double t4 = tx * ca - ty * sa; shy = sx * sa + shy * ca; sy = shx * sa + sy * ca; ty = tx * sa + ty * ca; sx = t0; shx = t2; tx = t4; } break; case AffineMatrixCommand.Scale: { double mm0 = creationPlan.x; double mm3 = creationPlan.y; sx *= mm0; shx *= mm0; tx *= mm0; shy *= mm3; sy *= mm3; ty *= mm3; } break; case AffineMatrixCommand.Skew: { double m_sx = 1; double m_sy = 1; double m_shx = Math.Tan(creationPlan.x); double m_shy = Math.Tan(creationPlan.y); double t0 = sx * m_sx + shy * m_shx; double t2 = shx * m_sx + sy * m_shx; double t4 = tx * m_sx + ty * m_shx + 0;//0=m.tx shy = sx * m_shy + shy * m_sy; sy = shx * m_shy + sy * m_sy; ty = tx * m_shy + ty * m_sy + 0;//0= m.ty; sx = t0; shx = t2; tx = t4; //return new Affine(1.0, Math.Tan(y), Math.Tan(x), 1.0, 0.0, 0.0); } break; case AffineMatrixCommand.Translate: { tx += creationPlan.x; ty += creationPlan.y; } break; case AffineMatrixCommand.Invert: { double d = CalculateDeterminantReciprocal(); double t0 = sy * d; sy = sx * d; shy = -shy * d; shx = -shx * d; double t4 = -tx * t0 - ty * shx; ty = -tx * shy - ty * sy; sx = t0; tx = t4; } break; } }
private Affine(Affine a, Affine b) { //copy from a //multiply with b sx = a.sx; shy = a.shy; shx = a.shx; sy = a.sy; tx = a.tx; ty = a.ty; MultiplyMatrix(ref sx, ref sy, ref shx, ref shy, ref tx, ref ty, b); }
//------------------------------------------ Construction private Affine(Affine copyFrom) { sx = copyFrom.sx; shy = copyFrom.shy; shx = copyFrom.shx; sy = copyFrom.sy; tx = copyFrom.tx; ty = copyFrom.ty; }