Ejemplo n.º 1
0
        static string RenderRectangle(XIR.Rect rectangle)
        {
            var base64 = string.Empty;

            var size   = new CGSize(rectangle.Width, rectangle.Height);
            var origin = new CGPoint(rectangle.X, rectangle.Y);

            // We want the absolute values of the size
            var workSize = new CGSize(Math.Abs(size.Width), Math.Abs(size.Height));

            // This is our scale factor for output
            var dstSize = new CGSize(100, 100);

            // Define our Height label variables
            var numHeightLabelBounds = CGSize.Empty;
            var heightLabelBounds    = CGSize.Empty;
            var heightBounds         = CGSize.Empty;

            // Obtain our label lines and bounding boxes of the labels
            var numHeightLine = GetLabel(string.Format("{0:0.########}", size.Height), out numHeightLabelBounds);
            var heightLine    = GetSubLabel("Height", out heightLabelBounds);

            heightBounds.Width  = NMath.Max(numHeightLabelBounds.Width, heightLabelBounds.Width);
            heightBounds.Height = NMath.Max(numHeightLabelBounds.Height, heightLabelBounds.Height);


            // Define our Width label variables
            var numWidthLabelBounds = CGSize.Empty;
            var widthLabelBounds    = CGSize.Empty;
            var widthBounds         = CGSize.Empty;

            // Obtain our label lines and bound boxes of the labels
            var numWidthLine = GetLabel(string.Format("{0:0.########}", size.Width), out numWidthLabelBounds);
            var widthLine    = GetSubLabel("Width", out widthLabelBounds);

            widthBounds.Width  = NMath.Max(numWidthLabelBounds.Width, widthLabelBounds.Width);
            widthBounds.Height = NMath.Max(numWidthLabelBounds.Height, widthLabelBounds.Height);


            // Define our Width label variables
            var originLabelBounds = CGSize.Empty;
            var xyLabelBounds     = CGSize.Empty;
            var originBounds      = CGSize.Empty;

            // Obtain our label lines and bound boxes of the labels
            var originLine = GetLabel(string.Format("({0:0.########}, {1:0.########})", origin.X, origin.Y), out originLabelBounds);
            var xyLine     = GetSubLabel("x, y", out xyLabelBounds);

            originBounds.Width  = NMath.Max(originLabelBounds.Width, xyLabelBounds.Width);
            originBounds.Height = NMath.Max(originLabelBounds.Height, xyLabelBounds.Height);

            // Calculate our scale based on our destination size
            var ratio = 1f;

            if (!workSize.IsEmpty)
            {
                if (workSize.Width > workSize.Height)
                {
                    ratio          = (float)workSize.Height / (float)workSize.Width;
                    dstSize.Height = (int)(dstSize.Height * ratio);
                }
                else
                {
                    ratio         = (float)workSize.Width / (float)workSize.Height;
                    dstSize.Width = (int)(dstSize.Width * ratio);
                }

                // Make sure we at least have something to draw if the values are very small
                dstSize.Width  = NMath.Max(dstSize.Width, 4f);
                dstSize.Height = NMath.Max(dstSize.Height, 4f);
            }
            else
            {
                dstSize = CGSize.Empty;
            }


            // Define graphic element sizes and offsets
            var lineWidth       = 2;
            var capSize         = 8f;
            var vCapIndent      = 3f;
            var separationSpace = 2f;
            var dotSize         = new CGSize(6, 6);

            var extraBoundingSpaceWidth  = (widthBounds.Width + separationSpace) * 2;
            var extraBoundingSpaceHeight = (heightBounds.Height + separationSpace) * 2;

            int width  = (int)(dstSize.Width + lineWidth + capSize + vCapIndent + extraBoundingSpaceWidth);
            int height = (int)(dstSize.Height + lineWidth + capSize + extraBoundingSpaceHeight + originBounds.Height * 2);

            var bytesPerRow = 4 * width;

            using (var context = new CGBitmapContext(
                       IntPtr.Zero, width, height,
                       8, bytesPerRow, CGColorSpace.CreateDeviceRGB(),
                       CGImageAlphaInfo.PremultipliedFirst))
            {
                // Clear the context with our background color
                context.SetFillColor(BackgroundColor.CGColor);
                context.FillRect(new CGRect(0, 0, width, height));

                // Setup our matrices so our 0,0 is top left corner.  Just makes it easier to layout
                context.ConcatCTM(context.GetCTM().Invert());
                var matrix = new CGAffineTransform(
                    1, 0, 0, -1, 0, height);

                context.ConcatCTM(matrix);

                context.SetStrokeColor(pen.CGColor);
                context.SetFillColor(pen.CGColor);
                context.SetLineWidth(lineWidth);

                context.SaveState();

                // We need to offset the drawing of our size segment rulers leaving room for labels
                var xOffSet = heightBounds.Width;
                var yOffset = ((height + originBounds.Height * 2) - extraBoundingSpaceHeight) / 2f - dstSize.Height / 2f;

                context.TranslateCTM(xOffSet, yOffset);

                context.AddEllipseInRect(new CGRect(vCapIndent - dotSize.Width / 2f, vCapIndent - dotSize.Height / 2f, dotSize.Width, dotSize.Height));
                context.FillPath();

                context.AddRect(new CGRect(vCapIndent, vCapIndent, dstSize.Width, dstSize.Height));

                context.StrokePath();

                context.RestoreState();

                // Setup our text matrix
                var textMatrix = new CGAffineTransform(
                    1, 0, 0, -1, 0, 0);

                context.TextMatrix = textMatrix;

                // Draw the Origin labels
                context.TextPosition = new CGPoint((xOffSet + vCapIndent) - originLabelBounds.Width / 2, originLabelBounds.Height);
                originLine.Draw(context);

                context.TextPosition = new CGPoint((xOffSet + vCapIndent) - xyLabelBounds.Width / 2, originLabelBounds.Height * 2);
                xyLine.Draw(context);


                // Draw the Height label
                var heightCenter = yOffset + ((dstSize.Height / 2) + ((vCapIndent + lineWidth) * 2));

                context.TextPosition = new CGPoint(heightBounds.Width / 2 - numHeightLabelBounds.Width / 2, heightCenter - heightBounds.Height / 2f);
                numHeightLine.Draw(context);

                context.TextPosition = new CGPoint(heightBounds.Width / 2 - heightLabelBounds.Width / 2, heightCenter + heightBounds.Height / 2f);
                heightLine.Draw(context);


                // Draw the Width label
                var widthOffsetX = heightBounds.Width + ((dstSize.Width / 2) - ((lineWidth + vCapIndent) * 2));//    xOffSet - vCapIndent - lineWidth + dstSize.Width / 2f;
                context.TextPosition = new CGPoint(widthOffsetX + (widthBounds.Width / 2 - numWidthLabelBounds.Width / 2), height - widthBounds.Height - 2f);
                numWidthLine.Draw(context);

                context.TextPosition = new CGPoint(widthOffsetX + (widthBounds.Width / 2 - widthLabelBounds.Width / 2), height - widthLabelBounds.Height / 2f);
                widthLine.Draw(context);

                // Get rid of our lines
                numHeightLine.Dispose();
                heightLine.Dispose();

                numWidthLine.Dispose();
                widthLine.Dispose();

                originLine.Dispose();
                xyLine.Dispose();

                // Convert to base64 for display
                var bitmap = new NSBitmapImageRep(context.ToImage());

                var data = bitmap.RepresentationUsingTypeProperties(NSBitmapImageFileType.Png);
                base64 = data.GetBase64EncodedString(NSDataBase64EncodingOptions.None);
            }

            return(String.Format(
                       "<figure>" +
                       "<figcatpion>" +
                       "Rectangle: " +
                       "<span class='var'>X</span> = <span class='value'>{0:0.########}</span>, " +
                       "<span class='var'>Y</span> = <span class='value'>{1:0.########}</span>, " +
                       "<span class='var'>Width</span> = <span class='value'>{2:0.########}</span>, " +
                       "<span class='var'>Height</span> = <span class='value'>{3:0.########}</span>" +
                       "</figcaption>" +
                       "<img width='{4}' height='{5}' src='data:image/png;base64,{6}' />" +
                       "</figure>",
                       origin.X, origin.Y,
                       size.Width, size.Height,
                       (int)width,
                       (int)height,
                       base64
                       ));
        }