Multiply() public static method

public static Multiply ( CGAffineTransform a, CGAffineTransform b ) : CGAffineTransform
a CGAffineTransform
b CGAffineTransform
return CGAffineTransform
Ejemplo n.º 1
0
			public void Draw(GraphicsHandler graphics, RectangleF rect)
			{
				var outerRadius = Radius.Width;
				var yscale = Radius.Height / Radius.Width;
				var center = Center;
				var origin = GradientOrigin;
				var scale = 1f;

				if (wrap != GradientWrapMode.Pad)
				{
					// use eto's transformrectangle as it'll make the rect encompass the resulting transformed area
					var boundRect = transform.Invert().ToEto().TransformRectangle(rect);

					// find max number of iterations we need to fill the bounding rectangle
					scale = GradientHelper.GetRadialScale(Center, Radius, GradientOrigin, boundRect);
				}

				if (Gradient == null || scale > lastScale)
				{
					var stops = GradientHelper.GetGradientStops(StartColor.ToCG(), EndColor.ToCG(), scale, wrap).ToList();
					lastScale = scale;
					Gradient = new CGGradient(CGColorSpace.CreateDeviceRGB(), stops.Select(r => r.Item2).ToArray(), stops.Select(r => (nfloat)r.Item1).ToArray());
				}
				else
				{
					scale = lastScale;
				}
				
				var scaledRect = new RectangleF(GradientOrigin - (GradientOrigin - Center + Radius) * scale, GradientOrigin + (Center + Radius - GradientOrigin) * scale);
				center = scaledRect.Center;
				outerRadius *= scale;

				// adjust center based on ellipse scale from gradient origin
				center.Y = origin.Y - (origin.Y - center.Y) / yscale;

				// scale to draw elliptical gradient
				var t = new CGAffineTransform(1, 0f, 0f, yscale, 0, origin.Y - origin.Y * yscale);
				t.Multiply(transform);

				graphics.Control.SaveState();
				graphics.Control.ConcatCTM(t);
				graphics.Control.DrawRadialGradient(Gradient, origin.ToNS(), 0, center.ToNS(), outerRadius, CGGradientDrawingOptions.DrawsAfterEndLocation | CGGradientDrawingOptions.DrawsBeforeStartLocation);
				graphics.Control.RestoreState();
			}
Ejemplo n.º 2
0
        public Matrix(RectangleF rect, PointF[] plgpts)
        {
            if (plgpts == null)
                throw new ArgumentNullException ("plgpts");
            if (plgpts.Length != 3)
                throw new ArgumentException ("plgpts");

            PointF p0 = plgpts [0];
            PointF p1 = plgpts [1];
            PointF p2 = plgpts [2];

            float m11 = (p1.X - p0.X) / rect.Width;
            float m12 = (p1.Y - p0.Y) / rect.Width;
            float m21 = (p2.X - p0.X) / rect.Height;
            float m22 = (p2.Y - p0.Y) / rect.Height;

            transform = CGAffineTransform.MakeTranslation(-rect.X, -rect.Y);
            transform.Multiply(new CGAffineTransform (m11, m12, m21, m22, p0.X, p0.Y));
        }
        /// <summary>
        /// Draws the specified portion of the specified Image at the specified location and with the specified size.
        /// 
        /// The destPoints specifies a parallelogram with the first point specifying the upper left corner, 
        /// second point specifying the upper right corner and the third point specifying the lower left corner.
        /// 
        /// The srcRect parameter specifies a rectangular portion of the image object to draw. This portion is scaled 
        /// up or down (in the case where source rectangle overruns the bounds of the image) to fit inside the rectangle 
        /// specified by the destRect parameter.  
        /// </summary>
        /// <param name="image">Image.</param>
        /// <param name="destPoints">Destination points.</param>
        /// <param name="srcRect">Source rect.</param>
        /// <param name="srcUnit">Source unit.</param>
        public void DrawImage(Image image, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit)
        {
            if (image == null)
                throw new ArgumentNullException ("image");
            if (destPoints == null)
                throw new ArgumentNullException ("destPoints");

            if (destPoints.Length < 3)
                throw new ArgumentException ("Destination points must be an array with a length of 3 or 4. " +
                                             "A length of 3 defines a parallelogram with the upper-left, upper-right, " +
                                             "and lower-left corners. A length of 4 defines a quadrilateral with the " +
                                             "fourth element of the array specifying the lower-right coordinate.");

            // Windows throws a Not Implemented error if the points are more than 3
            if (destPoints.Length > 3)
                throw new NotImplementedException ();

            var srcRect1 = srcRect;

            // If the source units are not the same we need to convert them
            // The reason we check for Pixel here is that our graphics already has the Pixel's baked into the model view transform
            if (srcUnit != graphicsUnit && srcUnit != GraphicsUnit.Pixel)
            {
                ConversionHelpers.GraphicsUnitConversion (srcUnit, graphicsUnit, image.HorizontalResolution, image.VerticalResolution,  ref srcRect1);
            }

            // Obtain the subImage
            var subImage = image.NativeCGImage.WithImageInRect (srcRect1);

            // If we do not have anything to draw then we exit here
            if (subImage.Width == 0 || subImage.Height == 0)
                return;

            // create our rectangle.  Offset is 0 because the CreateGeometricTransform bakes our x,y offset in there.
            var rect = new RectangleF (0,0, destPoints [1].X - destPoints [0].X, destPoints [2].Y - destPoints [0].Y);

            // We need to flip our Y axis so the image appears right side up
            var geoTransform = new CGAffineTransform (1, 0, 0, -1, 0, rect.Height);

            // Make sure we scale the image in case the source rectangle
            // overruns our subimage bounds (width and/or height)
            float scaleX = subImage.Width/srcRect1.Width;
            float scaleY = subImage.Height/srcRect1.Height;
            geoTransform.Scale (scaleX, scaleY);

            //var geott = GeomUtilities.CreateGeometricTransform (rect, destPoints);
            geoTransform.Multiply (GeomUtilities.CreateGeometricTransform (rect, destPoints));

            // Apply our transform to the context
            context.ConcatCTM (geoTransform);

            // now we draw our image.
            context.DrawImage(rect, subImage);

            // Now we revert our image transform from the context
            var revert = CGAffineTransform.CGAffineTransformInvert (geoTransform);
            context.ConcatCTM (revert);
        }
Ejemplo n.º 4
0
 public void Shear(float shearX, float shearY, MatrixOrder order)
 {
     var affine = new CGAffineTransform (1, shearY, shearX, 1, 0, 0);
     if (order == MatrixOrder.Append)
         transform.Multiply (affine);
     else {
         affine.Multiply (transform);
         transform = affine;
     }
 }
        /// <summary>
        /// Draws the specified Image at the specified location and with the specified shape and size.
        /// 
        /// The destPoints parameter specifies three points of a parallelogram. The three PointF structures 
        /// represent the upper-left, upper-right, and lower-left corners of the parallelogram. The fourth point 
        /// is extrapolated from the first three to form a parallelogram.
        /// 
        /// The image represented by the image object is scaled and sheared to fit the shape of the parallelogram 
        /// specified by the destPoints parameter.
        /// </summary>
        /// <param name="image">Image.</param>
        /// <param name="destPoints">Destination points.</param>
        public void DrawImage(Image image, PointF [] destPoints)
        {
            if (image == null)
                throw new ArgumentNullException ("image");
            if (destPoints == null)
                throw new ArgumentNullException ("destPoints");
            if (destPoints.Length < 3)
                throw new ArgumentException ("Destination points must be an array with a length of 3 or 4. " +
                                             "A length of 3 defines a parallelogram with the upper-left, upper-right, " +
                                             "and lower-left corners. A length of 4 defines a quadrilateral with the " +
                                             "fourth element of the array specifying the lower-right coordinate.");

            // Windows throws a Not Implemented error if the points are more than 3
            if (destPoints.Length > 3)
                throw new NotImplementedException ();

            // create our rectangle.  Offset is 0 because the CreateGeometricTransform bakes our x,y offset in there.
            var rect = new RectangleF (0,0, destPoints [1].X - destPoints [0].X, destPoints [2].Y - destPoints [0].Y);

            // We need to flip our Y axis so the image appears right side up
            var geoTransform = new CGAffineTransform (1, 0, 0, -1, 0, rect.Height);
            //var geott = GeomUtilities.CreateGeometricTransform (rect, destPoints);
            geoTransform.Multiply (GeomUtilities.CreateGeometricTransform (rect, destPoints));

            // Apply our transform to the context
            context.ConcatCTM (geoTransform);

            // now we draw our image.
            context.DrawImage(rect, image.NativeCGImage);

            // Now we revert our image transform from the context
            var revert = CGAffineTransform.CGAffineTransformInvert (geoTransform);
            context.ConcatCTM (revert);
        }