Exemple #1
0
        public void Render(GraphBuilder context, IImageProcessingContext <Rgba32> renderContext, GraphicsOptions renderOptions)
        {
            // top left is renderer's origin point

            if (LineDistanceVertical.HasValue)
            {
                float          interval   = context.ToPixelsVertical(LineDistanceVertical.Value);
                int            gridLineCt = 0;
                Action <float> loopBody   = y =>
                {
                    renderContext.DrawLines(MajorVerticalGridLineInterval > 0 && gridLineCt % MajorVerticalGridLineInterval == 0 ? MajorVerticalPen : VerticalPen, new PointF[] {
                        new PointF(context.GridRegion.Left, y),
                        new PointF(context.GridRegion.Right, y)
                    }, renderOptions);
                    gridLineCt++;
                };
                // 2 loops so we're guaranteed to be aligned to the origin and X-axis
                // note that major grid lines will overlap axes
                for (float y = context.GridRegion.Top + context.Origin.Y; y < context.GridRegion.Bottom; y += interval)
                {
                    loopBody(y);
                }
                gridLineCt = 0;
                for (float y = context.GridRegion.Top + context.Origin.Y; y > context.GridRegion.Top; y -= interval)
                {
                    loopBody(y);
                }
            }
            if (LineDistanceHorizontal.HasValue)
            {
                float          interval   = context.ToPixelsHorizontal(LineDistanceHorizontal.Value);
                int            gridLineCt = 0;
                Action <float> loopBody   = x =>
                {
                    renderContext.DrawLines(MajorHorizontalGridLineInterval > 0 && gridLineCt % MajorHorizontalGridLineInterval == 0 ? MajorHorizontalPen : HorizontalPen, new PointF[] {
                        new PointF(x, context.GridRegion.Top),
                        new PointF(x, context.GridRegion.Bottom)
                    }, renderOptions);
                    gridLineCt++;
                };

                // 2 loops so we're guaranteed to be aligned to the origin and Y-axis
                for (float x = context.GridRegion.Left + context.Origin.X; x < context.GridRegion.Right; x += interval)
                {
                    loopBody(x);
                }
                gridLineCt = 0;
                for (float x = context.GridRegion.Left + context.Origin.X; x > context.GridRegion.Left; x -= interval)
                {
                    loopBody(x);
                }
            }
        }
Exemple #2
0
 /// <summary>
 /// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
 /// </summary>
 /// <param name="source">The image this method extends.</param>
 /// <param name="options">The options.</param>
 /// <param name="color">The color.</param>
 /// <param name="thickness">The thickness.</param>
 /// <param name="points">The points.</param>
 /// <returns>The <see cref="Image{TPixel}"/>.</returns>>
 public static IImageProcessingContext DrawLines(
     this IImageProcessingContext source,
     ShapeGraphicsOptions options,
     Color color,
     float thickness,
     params PointF[] points) =>
 source.DrawLines(options, new SolidBrush(color), thickness, points);
Exemple #3
0
        private static IImageProcessingContext DrawStats(this IImageProcessingContext source, Font header, Font body,
                                                         string rank, string level, string required, DateTime lastLevelUp)
        {
            const float spacing = XpBarLength / 4f;
            const float y       = 117.5f;

            source.DrawLines(Color.HotPink, 2.5f, new PointF(XpBarX + spacing, y), new PointF(XpBarX + spacing, y + 52))
            .DrawLines(Color.HotPink, 2.5f, new PointF(XpBarX + spacing * 2, y), new PointF(XpBarX + spacing * 2, y + 52))
            .DrawLines(Color.HotPink, 2.5f, new PointF(XpBarX + spacing * 3, y), new PointF(XpBarX + spacing * 3, y + 52));

            var headerOptions = new TextGraphicsOptions {
                TextOptions = { HorizontalAlignment = HorizontalAlignment.Center }
            };

            var bodyOptions = new TextGraphicsOptions {
                TextOptions = { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Bottom, }
            };

            // need to use en-US since en-CA adds a . to month abbreviation (en-US -> Jan, en-CA -> Jan.)
            string lastLevelUpString = lastLevelUp == DateTime.MinValue ? "Never" : lastLevelUp.ToString("MMM dd yyyy", new CultureInfo("en-US"));

            source.DrawText(headerOptions, "Rank", header, Color.HotPink, new PointF(301, y)) // (XpBarX + spacing) / 2
            .DrawText(bodyOptions, rank, body, Color.DarkSlateGray, new PointF(301, 170))
            .DrawText(headerOptions, "Level", header, Color.HotPink, new PointF(430, y))      // ((XpBarX + spacing) / 2 + (XpBarX + spacing * 2)) / 2
            .DrawText(bodyOptions, level, body, Color.DarkSlateGray, new PointF(430, 170))
            .DrawText(headerOptions, "Required XP", header, Color.HotPink, new PointF(558, y))
            .DrawText(bodyOptions, required, body, Color.DarkSlateGray, new PointF(558, 170))
            .DrawText(headerOptions, "Last Level Up", header, Color.HotPink, new PointF(695, y))
            .DrawText(bodyOptions, lastLevelUpString, body, Color.DarkSlateGray, new PointF(695, 170));

            return(source);
        }
Exemple #4
0
        private void DrawGraticules(IImageProcessingContext img, GraticuleLabels graticules, Point <double> corner, int zoom)
        {
            var font = SixLabors.Fonts.SystemFonts.CreateFont("Arial", 8);

            foreach (var meridian in graticules.VerticalLabels)
            {
                var loc   = meridian.worldLocation;
                var pt    = TileUtils.PositionToGlobalPixel(new LatLong(loc.Lat, loc.Long), zoom, TileSize);
                var xpos  = pt.X - corner.X;
                var start = new PointF((float)xpos, 0);
                var end   = new PointF((float)xpos, TileSize);
                img.DrawLines(Rgba32.Gray, 1f, new PointF[] { start, end });
                try
                {
                    if (xpos < TileSize - 10)
                    {
                        img.DrawText(Math.Round(loc.Long, 2).ToString(), font, Rgba32.Black, new PointF((float)xpos, 50));
                    }
                }
                catch (Exception)
                {
                }
            }
            foreach (var parallel in graticules.HorizontalLabels)
            {
                var loc   = parallel.worldLocation;
                var pt    = TileUtils.PositionToGlobalPixel(new LatLong(loc.Lat, loc.Long), zoom, TileSize);
                var ypos  = pt.Y - corner.Y;
                var start = new PointF(0, (float)ypos);
                var end   = new PointF(TileSize, (float)ypos);
                img.DrawLines(Rgba32.Gray, 1f, new PointF[] { start, end });
                try
                {
                    img.DrawText(Math.Round(loc.Lat, 4).ToString(), font, Rgba32.Black, new PointF(50, (float)ypos));
                }
                catch (Exception)
                {
                }
            }
        }
        private void drawRandomLines(IImageProcessingContext pc, int width, int height)
        {
            const float stroke           = 1.5F;
            var         linesCount       = _options.CaptchaNoise.NoiseLinesCount;
            const int   distanceFromEdge = 10;

            for (var i = 0; i < linesCount; i++)
            {
                var x0 = _randomNumberProvider.NextNumber(distanceFromEdge, width - distanceFromEdge);
                var y0 = _randomNumberProvider.NextNumber(distanceFromEdge, height - distanceFromEdge);
                var x1 = _randomNumberProvider.NextNumber(distanceFromEdge, width - distanceFromEdge);
                var y1 = _randomNumberProvider.NextNumber(distanceFromEdge, height - distanceFromEdge);
                pc.DrawLines(Color.LightGray, stroke, new PointF(x0, y0), new PointF(x1, y1));
            }
        }
Exemple #6
0
        public void Render(GraphBuilder context, IImageProcessingContext <Rgba32> renderContext, GraphicsOptions options)
        {
            float leftBoundPixel   = context.GridRegion.Left;
            float rightBoundPixel  = context.GridRegion.Right;
            float topBoundPixel    = context.GridRegion.Top;
            float bottomBoundPixel = context.GridRegion.Bottom;

            var data = Data.Select(point => new
            {
                PixelLocation = context.ToPixels(((PointF)point)) + context.GridRegion.Position() + context.Origin,
                Data          = point
            }).Where(point => point.PixelLocation.X > leftBoundPixel && point.PixelLocation.X <rightBoundPixel && point.PixelLocation.Y> topBoundPixel && point.PixelLocation.Y < bottomBoundPixel)
                       .OrderBy(point => point.Data.X)
                       .ToArray();

            while (data.Length > 0)
            {
                List <PointF> pixels = data.TakeWhile(p => !p.Data.BreakLine).Select(p => p.PixelLocation).ToList();
                if (pixels.Count < data.Length)
                {
                    // add the line-breaking point
                    pixels.Add(data[pixels.Count].PixelLocation);
                }
                if (LinePen != null)
                {
                    renderContext.DrawLines(LinePen, pixels.ToArray(), options);
                }
                if (DataPointCircleRadius > 0)
                {
                    foreach (var pixel in pixels)
                    {
                        renderContext.Fill(PointColor, new SixLabors.Shapes.EllipsePolygon(pixel, DataPointCircleRadius), options);
                    }
                }
                data = data.Skip(pixels.Count).ToArray();
            }
        }
        public void DrawAxis(IImageProcessingContext ctx, float width, float height)
        {
            var font = SystemFonts.CreateFont("Arial", 20, SixLabors.Fonts.FontStyle.Regular);

            var blackPen      = Pens.Solid(Rgba32.ParseHex("#000000"), 1);
            var blackTransPen = Pens.Solid(Rgba32.ParseHex("#00005050"), 1);

            // Scale the cell size up until it's sane
            var cellSize = 1;

            while (cellSize * scale < 50)
            {
                cellSize++;
            }

            // Draw other thing
            for (int i = 1; i < width; i++)
            {
                var x = ScreenToX(i);

                // Draws every thing
                if (x % cellSize == 0)
                {
                    ctx.DrawLines(blackTransPen, new PointF[] { new PointF(i, 0), new PointF(i, height) });
                    ctx.DrawText(x.ToString(), font, new Rgba32(22, 33, 45, 66), new PointF(i, YToScreen(0)));
                }
            }

            // Draw other thing
            for (int i = 1; i < height; i++)
            {
                var y = ScreenToY(i);

                if (y % cellSize == 0)
                {
                    ctx.DrawLines(blackTransPen, new PointF[] { new PointF(0, i), new PointF(width, i) });

                    // skip drawing 0 twice
                    if (y != 0)
                    {
                        ctx.DrawText(y.ToString(), font, new Rgba32(22, 33, 45, 66), new PointF(XToScreen(0), i));
                    }
                }
            }

            // Draw x line
            for (int i = 1; i < width; i++)
            {
                var x = ScreenToX(i);

                if (x == 0)
                {
                    ctx.DrawLines(blackPen, new PointF[] { new PointF(i, 0), new PointF(i, height) });
                }
            }

            // Draw other thing
            for (int i = 1; i < height; i++)
            {
                var y = ScreenToY(i);

                if (y == 0)
                {
                    ctx.DrawLines(blackPen, new PointF[] { new PointF(0, i), new PointF(width, i) });
                }
            }
        }
 public static IImageProcessingContext DrawLines <TPixel>(this IImageProcessingContext source, IPen pen, float x0, float y0, float x1, float y1) where TPixel : struct, IPixel <TPixel>
 {
     return(source.DrawLines(pen, new PointF(x0, y0), new PointF(x1, y1)));
 }
Exemple #9
0
        public void Render(GraphBuilder context, IImageProcessingContext <Rgba32> renderContext, GraphicsOptions options)
        {
            // top and right
            PointF labelEndpoint;

            if (IsVertical)
            {
                PointF endpoint1 = new PointF(context.GridRegion.Left + context.Origin.X, context.GridRegion.Top + PositiveEndAxisMargin + ArrowLength);
                PointF endpoint2 = new PointF(context.GridRegion.Left + context.Origin.X, context.GridRegion.Bottom - NegativeEndAxisMargin - ArrowLength);
                labelEndpoint = endpoint1;

                renderContext.DrawLines(Brush, LineThickness, new PointF[] { endpoint1, endpoint2 });
                if (ArrowWidth > 0 && ArrowLength > 0)
                {
                    if (EnablePositiveEndArrow)
                    {
                        // top, add Y
                        renderContext.FillPolygon(ArrowColor, new PointF[] {
                            endpoint1 - new PointF(0, ArrowLength),
                            endpoint1 + new PointF(-ArrowWidth / 2, 0),
                            endpoint1 + new PointF(ArrowWidth / 2, 0)
                        }, options);
                    }
                    if (EnableNegativeEndArrow)
                    {
                        // bottom, subtract Y
                        renderContext.FillPolygon(ArrowColor, new PointF[] {
                            endpoint2 + new PointF(0, ArrowLength),
                            endpoint2 - new PointF(-ArrowWidth / 2, 0),
                            endpoint2 - new PointF(ArrowWidth / 2, 0)
                        }, options);
                    }
                }

                if (TitleLabel != null)
                {
                    RectangleF textBounds      = TextMeasurer.MeasureBounds(TitleLabel.Text, new RendererOptions(TitleLabel.Font));
                    int        higherDimension = (int)Math.Ceiling(Math.Max(textBounds.Width, textBounds.Height));
                    using (Image <Rgba32> textRenderImage = new Image <Rgba32>(higherDimension, higherDimension))
                    {
                        textRenderImage.Mutate(tempContext =>
                                               tempContext
                                               .DrawText(TitleLabel.Text, TitleLabel.Font, TitleLabel.Color, PointF.Empty, options)
                                               .Rotate(-90));
                        // TODO can I do this in the same IImageProcessingContext or do I have to stop, let it write, then read, then write
                        textRenderImage.MutateCropToColored();
                        PointF renderPosition = context.GridRegion.Position() + context.Origin + TitleLabel.Displacement - textRenderImage.Size() + new PointF(0, (textRenderImage.Height / 2) - ((context.Origin.Y + context.GridRegion.Top - endpoint1.Y) / 2));
                        renderContext.DrawImage(textRenderImage, textRenderImage.Size(), (Point)renderPosition, options);
                    }
                }
            }
            else
            {
                PointF endpoint1 = new PointF(context.GridRegion.Left + NegativeEndAxisMargin + ArrowLength, context.GridRegion.Top + context.Origin.Y);
                PointF endpoint2 = new PointF(context.GridRegion.Right - PositiveEndAxisMargin - ArrowLength, context.GridRegion.Top + context.Origin.Y);
                labelEndpoint = endpoint2;

                renderContext.DrawLines(Brush, LineThickness, new PointF[] { endpoint1, endpoint2 });
                if (ArrowWidth > 0 && ArrowLength > 0)
                {
                    if (EnableNegativeEndArrow)
                    {
                        // left, add X
                        renderContext.FillPolygon(ArrowColor, new PointF[] {
                            endpoint1 - new PointF(ArrowLength, 0),
                            endpoint1 + new PointF(0, -ArrowWidth / 2),
                            endpoint1 + new PointF(0, ArrowWidth / 2)
                        }, options);
                    }
                    if (EnablePositiveEndArrow)
                    {
                        // right, subtract X
                        renderContext.FillPolygon(ArrowColor, new PointF[] {
                            endpoint2 + new PointF(ArrowLength, 0),
                            endpoint2 - new PointF(0, -ArrowWidth / 2),
                            endpoint2 - new PointF(0, ArrowWidth / 2)
                        }, options);
                    }
                }

                if (TitleLabel != null)
                {
                    //var textBounds = TextMeasurer.Measure(TitleLabel.Text, new RendererOptions(TitleLabel.Font));
                    // TODO: why does this work without a textBounds displacement for re-origining?
                    var pos = context.GridRegion.Position() + context.Origin + TitleLabel.Displacement + new PointF(((endpoint2.X - (context.GridRegion.Left + context.Origin.X)) / 2), 0);
                    renderContext.DrawText(TitleLabel.Text, TitleLabel.Font, TitleLabel.Color, pos, options);
                }
            }

            if (EndpointLabel != null)
            {
                renderContext.DrawText(EndpointLabel.Text, EndpointLabel.Font, EndpointLabel.Color, labelEndpoint + EndpointLabel.Displacement, options);
            }
        }
 /// <summary>
 /// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
 /// </summary>
 /// <typeparam name="TPixel">The type of the color.</typeparam>
 /// <param name="source">The image this method extends.</param>
 /// <param name="color">The color.</param>
 /// <param name="thickness">The thickness.</param>
 /// <param name="points">The points.</param>
 /// <param name="options">The options.</param>
 /// <returns>The <see cref="Image{TPixel}"/>.</returns>>
 public static IImageProcessingContext <TPixel> DrawLines <TPixel>(this IImageProcessingContext <TPixel> source, TPixel color, float thickness, PointF[] points, GraphicsOptions options)
     where TPixel : struct, IPixel <TPixel>
 {
     return(source.DrawLines(new SolidBrush <TPixel>(color), thickness, points, options));
 }
Exemple #11
0
        private void DrawTextBox(IImageProcessingContext context, SoftwareKeyboardUiState state)
        {
            var inputTextRectangle = MeasureString(state.InputText, _inputTextFont);

            float boxWidth  = (int)(Math.Max(300, inputTextRectangle.Width + inputTextRectangle.X + 8));
            float boxHeight = 32;
            float boxY      = _panelRectangle.Y + 110;
            float boxX      = (int)((_panelRectangle.Width - boxWidth) / 2);

            RectangleF boxRectangle = new RectangleF(boxX, boxY, boxWidth, boxHeight);

            RectangleF boundRectangle = new RectangleF(_panelRectangle.X, boxY - _textBoxOutlineWidth,
                                                       _panelRectangle.Width, boxHeight + 2 * _textBoxOutlineWidth);

            context.Fill(_panelBrush, boundRectangle);

            context.Draw(_textBoxOutlinePen, boxRectangle);

            float inputTextX = (_panelRectangle.Width - inputTextRectangle.Width) / 2 - inputTextRectangle.X;
            float inputTextY = boxY + 5;

            var inputTextPosition = new PointF(inputTextX, inputTextY);

            context.DrawText(state.InputText, _inputTextFont, _textNormalColor, inputTextPosition);

            // Draw the cursor on top of the text and redraw the text with a different color if necessary.

            Color  cursorTextColor;
            IBrush cursorBrush;
            Pen    cursorPen;

            float cursorPositionYTop    = inputTextY + 1;
            float cursorPositionYBottom = cursorPositionYTop + _inputTextFontSize + 1;
            float cursorPositionXLeft;
            float cursorPositionXRight;

            bool cursorVisible = false;

            if (state.CursorBegin != state.CursorEnd)
            {
                Debug.Assert(state.InputText.Length > 0);

                cursorTextColor = _textSelectedColor;
                cursorBrush     = _selectionBoxBrush;
                cursorPen       = _selectionBoxPen;

                string textUntilBegin = state.InputText.Substring(0, state.CursorBegin);
                string textUntilEnd   = state.InputText.Substring(0, state.CursorEnd);

                var selectionBeginRectangle = MeasureString(textUntilBegin, _inputTextFont);
                var selectionEndRectangle   = MeasureString(textUntilEnd, _inputTextFont);

                cursorVisible        = true;
                cursorPositionXLeft  = inputTextX + selectionBeginRectangle.Width + selectionBeginRectangle.X;
                cursorPositionXRight = inputTextX + selectionEndRectangle.Width + selectionEndRectangle.X;
            }
            else
            {
                cursorTextColor = _textOverCursorColor;
                cursorBrush     = _cursorBrush;
                cursorPen       = _cursorPen;

                if (state.TextBoxBlinkCounter < TextBoxBlinkThreshold)
                {
                    // Show the blinking cursor.

                    int    cursorBegin         = Math.Min(state.InputText.Length, state.CursorBegin);
                    string textUntilCursor     = state.InputText.Substring(0, cursorBegin);
                    var    cursorTextRectangle = MeasureString(textUntilCursor, _inputTextFont);

                    cursorVisible       = true;
                    cursorPositionXLeft = inputTextX + cursorTextRectangle.Width + cursorTextRectangle.X;

                    if (state.OverwriteMode)
                    {
                        // The blinking cursor is in overwrite mode so it takes the size of a character.

                        if (state.CursorBegin < state.InputText.Length)
                        {
                            textUntilCursor      = state.InputText.Substring(0, cursorBegin + 1);
                            cursorTextRectangle  = MeasureString(textUntilCursor, _inputTextFont);
                            cursorPositionXRight = inputTextX + cursorTextRectangle.Width + cursorTextRectangle.X;
                        }
                        else
                        {
                            cursorPositionXRight = cursorPositionXLeft + _inputTextFontSize / 2;
                        }
                    }
                    else
                    {
                        // The blinking cursor is in insert mode so it is only a line.
                        cursorPositionXRight = cursorPositionXLeft;
                    }
                }
                else
                {
                    cursorPositionXLeft  = inputTextX;
                    cursorPositionXRight = inputTextX;
                }
            }

            if (state.TypingEnabled && cursorVisible)
            {
                float cursorWidth  = cursorPositionXRight - cursorPositionXLeft;
                float cursorHeight = cursorPositionYBottom - cursorPositionYTop;

                if (cursorWidth == 0)
                {
                    PointF[] points = new PointF[]
                    {
                        new PointF(cursorPositionXLeft, cursorPositionYTop),
                        new PointF(cursorPositionXLeft, cursorPositionYBottom),
                    };

                    context.DrawLines(cursorPen, points);
                }
                else
                {
                    var cursorRectangle = new RectangleF(cursorPositionXLeft, cursorPositionYTop, cursorWidth, cursorHeight);

                    context.Draw(cursorPen, cursorRectangle);
                    context.Fill(cursorBrush, cursorRectangle);

                    Image <Argb32> textOverCursor = new Image <Argb32>((int)cursorRectangle.Width, (int)cursorRectangle.Height);
                    textOverCursor.Mutate(context =>
                    {
                        var textRelativePosition = new PointF(inputTextPosition.X - cursorRectangle.X, inputTextPosition.Y - cursorRectangle.Y);
                        context.DrawText(state.InputText, _inputTextFont, cursorTextColor, textRelativePosition);
                    });

                    var cursorPosition = new Point((int)cursorRectangle.X, (int)cursorRectangle.Y);
                    context.DrawImage(textOverCursor, cursorPosition, 1);
                }
            }
            else if (!state.TypingEnabled)
            {
                // Just draw a semi-transparent rectangle on top to fade the component with the background.
                // TODO (caian): This will not work if one decides to add make background semi-transparent as well.

                context.Fill(_disabledBrush, boundRectangle);
            }
        }
Exemple #12
0
 /// <summary>
 /// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
 /// </summary>
 /// <typeparam name="TPixel">The type of the color.</typeparam>
 /// <param name="source">The image this method extends.</param>
 /// <param name="options">The options.</param>
 /// <param name="color">The color.</param>
 /// <param name="thickness">The thickness.</param>
 /// <param name="points">The points.</param>
 /// <returns>The <see cref="Image{TPixel}"/>.</returns>>
 public static IImageProcessingContext <TPixel> DrawLines <TPixel>(this IImageProcessingContext <TPixel> source, GraphicsOptions options, TPixel color, float thickness, params PointF[] points)
     where TPixel : struct, IPixel <TPixel>
 => source.DrawLines(options, new SolidBrush <TPixel>(color), thickness, points);