Exemplo n.º 1
0
 protected void ProduceResponse(HttpContext context, string title, RenderContext ctx, Size tileSize,
                                AbstractMatrix transform,
                                bool transparent = false)
 {
     ProduceResponse(context, this, title, ctx, tileSize, transform, transparent,
                     (context.Items["RouteData"] as System.Web.Routing.RouteData).Values);
 }
        public bool Equals(AbstractMatrix <T> x, AbstractMatrix <T> y)
        {
            if (ReferenceEquals(x, null))
            {
                return(false);
            }
            if (ReferenceEquals(y, null))
            {
                return(false);
            }

            if (ReferenceEquals(x, y))
            {
                return(true);
            }
            if (x.Size != y.Size)
            {
                return(false);
            }

            for (int i = 1; i <= x.Size; i++)
            {
                for (int j = 1; j <= x.Size; j++)
                {
                    if (!x[i, j].Equals(y[i, j]))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
        public void Sum_SquarePlusSquareEqualsDiagonal_PositiveTest()
        {
            AbstractMatrix <int> matr         = new SquareMatrix <int>(2, new int[] { 1, 2, 3, 4 });
            AbstractMatrix <int> smatr        = new SquareMatrix <int>(2, new int[] { 1, -2, -3, 4 });
            AbstractMatrix <int> actualResult = matr.Sum <int>(smatr);

            Assert.IsTrue(actualResult.GetType().ToString() == "Logic.DiagonalMatrix`1[System.Int32]");
        }
        public void Sum_IntInputValues_PositiveTest()
        {
            AbstractMatrix <int> matr           = new SquareMatrix <int>(2, new int[] { 1, 2, 3, 4 });
            AbstractMatrix <int> smatr          = new SymmetricMatrix <int>(2, new int[] { 1, 1 });
            AbstractMatrix <int> actualResult   = matr.Sum <int>(smatr);
            AbstractMatrix <int> expectedResult = new SquareMatrix <int>(2, new int[] { 2, 3, 4, 4 });

            Assert.IsTrue((new MatrixComparer <int>()).Equals(actualResult, expectedResult));
        }
Exemplo n.º 5
0
        public void SymByExpressionMatrix <T>(AbstractMatrix <T> abstractMatrix1, AbstractMatrix <T> abstractMatrix2, AbstractMatrix <T> result)
        {
            var matrix3 = abstractMatrix1.SymByExpression(abstractMatrix2);

            for (int i = 0; i < abstractMatrix1.Lenght; i++)
            {
                for (int j = 0; j < abstractMatrix1.Lenght; j++)
                {
                    Assert.AreEqual(result[i, j], matrix3[i, j]);
                }
            }
        }
Exemplo n.º 6
0
        private static void ShowMatrix <T>(AbstractMatrix <T> a, string message)
        {
            Console.WriteLine(message);

            for (int i = 0; i < a.Size; i++)
            {
                for (int j = 0; j < a.Size; j++)
                {
                    Console.Write(a[i, j] + "\t");
                }
                Console.WriteLine();
            }
        }
Exemplo n.º 7
0
        public static AbstractMatrix <T> SumMatrix <T>(this AbstractMatrix <T> matrix, AbstractMatrix <T> otherMatrix)
        {
            AbstractMatrix <T> newMatrix = new SquareMatrix <T>(matrix.Size);
            Func <T, T, T>     addMethod = CreateAdd <T>();

            for (int i = 0; i < matrix.Size; i++)
            {
                for (int j = 0; j < matrix.Size; j++)
                {
                    newMatrix[i, j] = addMethod(matrix[i, j], otherMatrix[i, j]);
                }
            }
            return(newMatrix);
        }
        static void Main(string[] args)
        {
            AbstractMatrix <int>        matrix   = new SquareMatrix <int>(3);
            ListenersChangeMatrix <int> listener = new ListenersChangeMatrix <int>(matrix);

            matrix[0, 0] = 1;
            matrix[0, 1] = 2;
            matrix[0, 2] = 3;
            matrix[1, 0] = 4;
            matrix[1, 1] = 5;
            matrix[1, 2] = 6;
            matrix[2, 0] = 7;
            matrix[2, 1] = 8;
            matrix[2, 2] = 9;


            AbstractMatrix <int>        matrix2   = new TriangularMatrix <int>(3);
            ListenersChangeMatrix <int> listener2 = new ListenersChangeMatrix <int>(matrix2);

            matrix2[0, 0] = 1;
            matrix2[1, 0] = 2;
            matrix2[1, 1] = 3;
            matrix2[2, 0] = 4;
            matrix2[2, 1] = 5;
            matrix2[2, 2] = 6;


            AbstractMatrix <int>        matrix4   = new DiagonalMatrix <int>(3);
            ListenersChangeMatrix <int> listener3 = new ListenersChangeMatrix <int>(matrix4);

            matrix4[0, 0] = 1;
            matrix4[1, 1] = 2;
            matrix4[2, 2] = 3;


            AbstractMatrix <int> matrix3 = matrix4.SumMatrix(matrix4);

            for (int i = 0; i < matrix3.Size; i++)
            {
                for (int j = 0; j < matrix3.Size; j++)
                {
                    Console.Write(" " + matrix3[i, j] + " ");
                }
                Console.WriteLine();
            }
        }
Exemplo n.º 9
0
            private static void RenderToGraphics(RenderContext ctx, int rot, float translateX, float translateY, AbstractGraphics graphics)
            {
                graphics.TranslateTransform(translateX, translateY);
                graphics.RotateTransform(rot * 90);

                if (ctx.DrawBorder && ctx.ClipPath != null)
                {
                    using (graphics.Save())
                    {
                        // Render border in world space
                        AbstractMatrix m = ctx.ImageSpaceToWorldSpace;
                        graphics.MultiplyTransform(m);
                        AbstractPen pen = new AbstractPen(ctx.Styles.imageBorderColor, 0.2f);

                        // SVG/PdfSharp can't ExcludeClip so we take advantage of the fact that we know
                        // the path starts on the left edge and proceeds clockwise. We extend the
                        // path with a counterclockwise border around it, then use that to exclude
                        // the original path's region for rendering the border.
                        RectangleF bounds = PathUtil.Bounds(ctx.ClipPath);
                        bounds.Inflate(2 * (float)pen.Width, 2 * (float)pen.Width);
                        List <byte>   types  = new List <byte>(ctx.ClipPath.Types);
                        List <PointF> points = new List <PointF>(ctx.ClipPath.Points);

                        PointF key = points[0];
                        points.Add(new PointF(bounds.Left, key.Y)); types.Add(1);
                        points.Add(new PointF(bounds.Left, bounds.Bottom)); types.Add(1);
                        points.Add(new PointF(bounds.Right, bounds.Bottom)); types.Add(1);
                        points.Add(new PointF(bounds.Right, bounds.Top)); types.Add(1);
                        points.Add(new PointF(bounds.Left, bounds.Top)); types.Add(1);
                        points.Add(new PointF(bounds.Left, key.Y)); types.Add(1);
                        points.Add(new PointF(key.X, key.Y)); types.Add(1);

                        graphics.IntersectClip(new AbstractPath(points.ToArray(), types.ToArray()));
                        graphics.DrawPath(pen, ctx.ClipPath);
                    }
                }

                using (graphics.Save())
                {
                    ctx.Render(graphics);
                }
            }
Exemplo n.º 10
0
        public static AbstractMatrix <T> SumByDynamic <T>(this AbstractMatrix <T> matrix1, AbstractMatrix <T> matrix2)
        {
            if (matrix1.Lenght != matrix2.Lenght)
            {
                throw new ArgumentException("Matrixs must have same lenght");
            }

            var resultMatrix = new T[matrix1.Lenght, matrix1.Lenght];

            for (int i = 0; i < matrix1.Lenght; i++)
            {
                for (int j = 0; j < matrix1.Lenght; j++)
                {
                    T result;
                    try
                    {
                        result = (T)((dynamic)matrix1[i, j] + matrix2[i, j]);
                    }
                    catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ex)
                    {
                        throw new NotSupportedException(nameof(T), ex);
                    }
                    resultMatrix[i, j] = result;
                }
            }

            int maxCount = matrix1.Count > matrix2.Count ? matrix1.Count : matrix2.Count;

            if (maxCount == matrix1.Lenght * matrix1.Lenght)
            {
                return(new SquareMatrix <T>(resultMatrix));
            }
            else if (maxCount == matrix1.Lenght)
            {
                return(new DiagonalMatrix <T>(resultMatrix));
            }
            else
            {
                return(new SymmetricMatrix <T>(resultMatrix));
            }
        }
Exemplo n.º 11
0
        public static AbstractMatrix <T> SymByExpression <T>(this AbstractMatrix <T> matrix1, AbstractMatrix <T> matrix2)
        {
            if (matrix1.Lenght != matrix2.Lenght)
            {
                throw new ArgumentException("Matrixs must have same lenght");
            }

            var resultMatrix = new T[matrix1.Lenght, matrix1.Lenght];

            for (int i = 0; i < matrix1.Lenght; i++)
            {
                for (int j = 0; j < matrix1.Lenght; j++)
                {
                    T result;
                    try
                    {
                        result = Add <T>()(matrix1[i, j], matrix2[i, j]);
                    }
                    catch (InvalidOperationException ex)
                    {
                        throw new NotSupportedException("", ex);;
                    }
                    resultMatrix[i, j] = result;
                }
            }

            int maxCount = matrix1.Count > matrix2.Count ? matrix1.Count : matrix2.Count;

            if (maxCount == matrix1.Lenght * matrix1.Lenght)
            {
                return(new SquareMatrix <T>(resultMatrix));
            }
            else if (maxCount == matrix1.Lenght)
            {
                return(new DiagonalMatrix <T>(resultMatrix));
            }
            else
            {
                return(new SymmetricMatrix <T>(resultMatrix));
            }
        }
Exemplo n.º 12
0
        public void AddTest()
        {
            SymmetricMatrix <int> firstMatrix = new SymmetricMatrix <int>(new int[, ] {
                { 1, 1, 1 }, { 1, 2, 1 }, { 1, 1, 3 }
            });
            DiagonalMatrix <int> secondMatrix = new DiagonalMatrix <int>(new int[, ] {
                { 1, 0, 0 }, { 0, 2, 0 }, { 0, 0, 3 }
            });
            SquareMatrix <int> expectedMatrix = new SquareMatrix <int>(new int[, ] {
                { 2, 1, 1 }, { 1, 4, 1 }, { 1, 1, 6 }
            });

            AbstractMatrix <int> resultMatrix = firstMatrix.AddMatrix(secondMatrix);

            for (int i = 0; i < firstMatrix.Dimension; i++)
            {
                for (int j = 0; j < firstMatrix.Dimension; j++)
                {
                    Assert.AreEqual(expectedMatrix[i, j], resultMatrix[i, j]);
                }
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Add matrix
        /// </summary>
        /// <typeparam name="T">type parameter</typeparam>
        /// <param name="matrix">matrix first term</param>
        /// <param name="matrixForAdd">matrix second term</param>
        /// <returns>matrix which is the sum of two matrix</returns>
        public static AbstractMatrix <T> AddMatrix <T>(this AbstractMatrix <T> matrix, AbstractMatrix <T> matrixForAdd)
        {
            if (matrix == null || matrixForAdd == null)
            {
                throw new ArgumentNullException("Matrix must be not null");
            }

            if (matrix.Dimension != matrixForAdd.Dimension)
            {
                throw new ArgumentException("The matrix dimension must match");
            }

            SquareMatrix <T> result = new SquareMatrix <T>(matrix.Dimension);

            for (int i = 0; i < matrix.Dimension; i++)
            {
                for (int j = 0; j < matrix.Dimension; j++)
                {
                    result[i, j] = (dynamic)matrix[i, j] + (dynamic)matrixForAdd[i, j];
                }
            }

            return(result);
        }
Exemplo n.º 14
0
            public override void Process(ResourceManager resourceManager)
            {
                //
                // Jump
                //
                int jump = GetIntOption("jump", 6).Clamp(0, 20);

                //
                // Content & Coordinates
                //
                Selector selector;
                Location loc;

                if (Context.Request.HttpMethod == "POST")
                {
                    Sector sector;
                    bool   lint = GetBoolOption("lint", defaultValue: false);
                    Func <ErrorLogger.Record, bool> filter = null;
                    if (lint)
                    {
                        bool hide_uwp = GetBoolOption("hide-uwp", defaultValue: false);
                        bool hide_tl  = GetBoolOption("hide-tl", defaultValue: false);
                        filter = (ErrorLogger.Record record) =>
                        {
                            if (hide_uwp && record.message.StartsWith("UWP"))
                            {
                                return(false);
                            }
                            if (hide_tl && record.message.StartsWith("UWP: TL"))
                            {
                                return(false);
                            }
                            return(true);
                        };
                    }

                    ErrorLogger errors = new ErrorLogger(filter);
                    sector = GetPostedSector(Context.Request, errors) ??
                             throw new HttpError(400, "Bad Request", "Either file or data must be supplied in the POST data.");
                    if (lint && !errors.Empty)
                    {
                        throw new HttpError(400, "Bad Request", errors.ToString());
                    }

                    int hex = GetIntOption("hex", Astrometrics.SectorCentralHex);
                    loc      = new Location(new Point(0, 0), hex);
                    selector = new HexSectorSelector(resourceManager, sector, loc.Hex, jump);
                }
                else
                {
                    // NOTE: This (re)initializes a static data structure used for
                    // resolving names into sector locations, so needs to be run
                    // before any other objects (e.g. Worlds) are loaded.
                    SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));

                    if (HasOption("sector") && HasOption("hex"))
                    {
                        string sectorName = GetStringOption("sector");
                        int    hex        = GetIntOption("hex", 0);
                        Sector sector     = map.FromName(sectorName) ??
                                            throw new HttpError(404, "Not Found", $"The specified sector '{sectorName}' was not found.");

                        loc = new Location(sector.Location, hex);
                    }
                    else if (HasLocation())
                    {
                        loc = GetLocation();
                    }
                    else
                    {
                        loc = Location.Empty;
                    }
                    selector = new HexSelector(map, resourceManager, loc, jump);
                }


                //
                // Scale
                //
                double scale = GetDoubleOption("scale", 64).Clamp(MinScale, MaxScale);

                //
                // Options & Style
                //
                MapOptions options = MapOptions.BordersMajor | MapOptions.BordersMinor | MapOptions.ForceHexes;
                Style      style   = Style.Poster;

                ParseOptions(ref options, ref style);

                //
                // Border
                //
                bool border = GetBoolOption("border", defaultValue: true);

                //
                // Clip
                //
                bool clip = GetBoolOption("clip", defaultValue: true);

                // Hex Rotation
                int hrot = GetIntOption("hrotation", defaultValue: 0);

                //
                // What to render
                //

                RectangleF tileRect = new RectangleF();

                Point coords = Astrometrics.LocationToCoordinates(loc);

                tileRect.X      = coords.X - jump - 1;
                tileRect.Width  = jump + 1 + jump;
                tileRect.Y      = coords.Y - jump - 1;
                tileRect.Height = jump + 1 + jump;

                // Account for jagged hexes
                tileRect.Y += (coords.X % 2 == 0) ? 0 : 0.5f;
                tileRect.Inflate(0.35f, 0.15f);

                Size tileSize = new Size((int)Math.Floor(tileRect.Width * scale * Astrometrics.ParsecScaleX), (int)Math.Floor(tileRect.Height * scale * Astrometrics.ParsecScaleY));


                // Construct clipping path
                List <Point> clipPath = new List <Point>(jump * 6 + 1);
                Point        cur      = coords;

                for (int i = 0; i < jump; ++i)
                {
                    // Move J parsecs to the upper-left (start of border path logic)
                    cur = Astrometrics.HexNeighbor(cur, 1);
                }
                clipPath.Add(cur);
                for (int dir = 0; dir < 6; ++dir)
                {
                    for (int i = 0; i < jump; ++i)
                    {
                        cur = Astrometrics.HexNeighbor(cur, (dir + 3) % 6); // Clockwise from upper left
                        clipPath.Add(cur);
                    }
                }

                Stylesheet styles = new Stylesheet(scale, options, style);

                // If any names are showing, show them all
                if (styles.worldDetails.HasFlag(WorldDetails.KeyNames))
                {
                    styles.worldDetails |= WorldDetails.AllNames;
                }

                // Compute path
                RenderUtil.HexEdges(styles.hexStyle == HexStyle.Square ? PathUtil.PathType.Square : PathUtil.PathType.Hex,
                                    out float[] edgeX, out float[] edgeY);
                PathUtil.ComputeBorderPath(clipPath, edgeX, edgeY, out PointF[] boundingPathCoords, out byte[] boundingPathTypes);

                AbstractMatrix transform = AbstractMatrix.Identity;

                if (hrot != 0)
                {
                    ApplyHexRotation(hrot, styles, ref tileSize, ref transform);
                }

                RenderContext ctx = new RenderContext(resourceManager, selector, tileRect, scale, options, styles, tileSize)
                {
                    DrawBorder           = border,
                    ClipOutsectorBorders = true,

                    // TODO: Widen path to allow for single-pixel border
                    ClipPath = clip ? new AbstractPath(boundingPathCoords, boundingPathTypes) : null
                };

                ProduceResponse(Context, "Jump Map", ctx, tileSize, transform, transparent: clip);
            }
 public ListenersChangeMatrix(AbstractMatrix <T> matrix)
 {
     matrix.Change += ListenerMsg;
 }
Exemplo n.º 16
0
        protected static void ApplyHexRotation(int hrot, Stylesheet stylesheet, ref Size bitmapSize, ref AbstractMatrix transform)
        {
            float  degrees   = -hrot;
            double radians   = degrees * Math.PI / 180f;
            double newWidth  = Math.Abs(Math.Sin(radians)) * bitmapSize.Height + Math.Abs(Math.Cos(radians)) * bitmapSize.Width;
            double newHeight = Math.Abs(Math.Sin(radians)) * bitmapSize.Width + Math.Abs(Math.Cos(radians)) * bitmapSize.Height;

            transform.TranslatePrepend((float)newWidth / 2, (float)newHeight / 2);
            transform.RotatePrepend(-degrees);
            transform.TranslatePrepend(-bitmapSize.Width / 2, -bitmapSize.Height / 2);
            bitmapSize.Width  = (int)Math.Ceiling(newWidth);
            bitmapSize.Height = (int)Math.Ceiling(newHeight);

            stylesheet.hexRotation = (float)degrees;
            stylesheet.microBorders.textStyle.Rotation = degrees;
        }
Exemplo n.º 17
0
            protected void ProduceResponse(HttpContext context, ITypeAccepter accepter, string title, RenderContext ctx, Size tileSize,
                                           AbstractMatrix transform,
                                           bool transparent = false, IDictionary <string, object> queryDefaults = null)
            {
                // New-style Options

                #region URL Parameters
                // TODO: move to ParseOptions (maybe - requires options to be parsed after stylesheet creation?)
                if (GetBoolOption("sscoords", queryDefaults: queryDefaults, defaultValue: false))
                {
                    ctx.Styles.hexCoordinateStyle = HexCoordinateStyle.Subsector;
                }

                if (GetBoolOption("allhexes", queryDefaults: queryDefaults, defaultValue: false))
                {
                    ctx.Styles.numberAllHexes = true;
                }

                if (GetBoolOption("nogrid", queryDefaults: queryDefaults, defaultValue: false))
                {
                    ctx.Styles.parsecGrid.visible = false;
                }

                if (!GetBoolOption("routes", queryDefaults: queryDefaults, defaultValue: true))
                {
                    ctx.Styles.macroRoutes.visible = false;
                    ctx.Styles.microRoutes.visible = false;
                }

                if (!GetBoolOption("rifts", queryDefaults: queryDefaults, defaultValue: true))
                {
                    ctx.Styles.showRiftOverlay = false;
                }

                if (GetBoolOption("po", queryDefaults: queryDefaults, defaultValue: false))
                {
                    ctx.Styles.populationOverlay.visible = true;
                }

                if (GetBoolOption("im", queryDefaults: queryDefaults, defaultValue: false))
                {
                    ctx.Styles.importanceOverlay.visible = true;
                }

                if (GetBoolOption("cp", queryDefaults: queryDefaults, defaultValue: false))
                {
                    ctx.Styles.capitalOverlay.visible = true;
                }

                if (GetBoolOption("stellar", queryDefaults: queryDefaults, defaultValue: false))
                {
                    ctx.Styles.showStellarOverlay = true;
                }

                ctx.Styles.dimUnofficialSectors    = GetBoolOption("dimunofficial", queryDefaults: queryDefaults, defaultValue: false);
                ctx.Styles.colorCodeSectorStatus   = GetBoolOption("review", queryDefaults: queryDefaults, defaultValue: false);
                ctx.Styles.droyneWorlds.visible    = GetBoolOption("dw", queryDefaults: queryDefaults, defaultValue: false);
                ctx.Styles.minorHomeWorlds.visible = GetBoolOption("mh", queryDefaults: queryDefaults, defaultValue: false);
                ctx.Styles.ancientsWorlds.visible  = GetBoolOption("an", queryDefaults: queryDefaults, defaultValue: false);

                // TODO: Return an error if pattern is invalid?
                ctx.Styles.highlightWorldsPattern = HighlightWorldPattern.Parse(
                    GetStringOption("hw", queryDefaults: queryDefaults, defaultValue: String.Empty).Replace(' ', '+'));
                ctx.Styles.highlightWorlds.visible = ctx.Styles.highlightWorldsPattern != null;

                double devicePixelRatio = GetDoubleOption("dpr", defaultValue: 1, queryDefaults: queryDefaults);
                devicePixelRatio = Math.Round(devicePixelRatio, 1);
                if (devicePixelRatio <= 0)
                {
                    devicePixelRatio = 1;
                }
                if (devicePixelRatio > 2)
                {
                    devicePixelRatio = 2;
                }

                bool dataURI = GetBoolOption("datauri", queryDefaults: queryDefaults, defaultValue: false);

                if (GetStringOption("milieu", SectorMap.DEFAULT_MILIEU) != SectorMap.DEFAULT_MILIEU)
                {
                    // TODO: Make this declarative in resource files.
                    if (ctx.Styles.macroBorders.visible)
                    {
                        ctx.Styles.macroBorders.visible = false;
                        ctx.Styles.microBorders.visible = true;
                    }
                    ctx.Styles.macroNames.visible  = false;
                    ctx.Styles.macroRoutes.visible = false;
                }
                #endregion

                MemoryStream ms = null;
                if (dataURI)
                {
                    ms = new MemoryStream();
                }
                Stream outputStream = ms ?? Context.Response.OutputStream;

                if (accepter.Accepts(context, ContentTypes.Image.Svg, ignoreHeaderFallbacks: true))
                {
                    #region SVG Generation
                    using (var svg = new SVGGraphics(tileSize.Width, tileSize.Height))
                    {
                        RenderToGraphics(ctx, transform, svg);

                        using (var stream = new MemoryStream())
                        {
                            svg.Serialize(new StreamWriter(stream));
                            context.Response.ContentType = ContentTypes.Image.Svg;
                            if (!dataURI)
                            {
                                context.Response.AddHeader("content-length", stream.Length.ToString());
                                context.Response.AddHeader("content-disposition", $"inline;filename=\"{Util.SanitizeFilename(title)}.svg\"");
                            }
                            stream.WriteTo(outputStream);
                        }
                    }
                    #endregion
                }

                else if (accepter.Accepts(context, ContentTypes.Application.Pdf, ignoreHeaderFallbacks: true))
                {
                    #region PDF Generation
                    using (var document = new PdfDocument())
                    {
                        document.Version       = 14; // 1.4 for opacity
                        document.Info.Title    = title;
                        document.Info.Author   = "Joshua Bell";
                        document.Info.Creator  = "TravellerMap.com";
                        document.Info.Subject  = DateTime.Now.ToString("F", CultureInfo.InvariantCulture);
                        document.Info.Keywords = "The Traveller game in all forms is owned by Far Future Enterprises. Copyright (C) 1977 - 2019 Far Future Enterprises. Traveller is a registered trademark of Far Future Enterprises.";

                        // TODO: Credits/Copyright
                        // This is close, but doesn't define the namespace correctly:
                        // document.Info.Elements.Add( new KeyValuePair<string, PdfItem>( "/photoshop/Copyright", new PdfString( "HelloWorld" ) ) );

                        PdfPage page = document.AddPage();

                        // NOTE: only PageUnit currently supported in MGraphics is Points
                        page.Width  = XUnit.FromPoint(tileSize.Width);
                        page.Height = XUnit.FromPoint(tileSize.Height);

                        using (var gfx = new PdfSharpGraphics(XGraphics.FromPdfPage(page)))
                        {
                            RenderToGraphics(ctx, transform, gfx);

                            using (var stream = new MemoryStream())
                            {
                                document.Save(stream, closeStream: false);
                                context.Response.ContentType = ContentTypes.Application.Pdf;
                                if (!dataURI)
                                {
                                    context.Response.AddHeader("content-length", stream.Length.ToString());
                                    context.Response.AddHeader("content-disposition", $"inline;filename=\"{Util.SanitizeFilename(title)}.pdf\"");
                                }
                                stream.WriteTo(outputStream);
                            }
                        }
                    }
                    #endregion
                }
                else
                {
                    #region Bitmap Generation
                    int width  = (int)Math.Floor(tileSize.Width * devicePixelRatio);
                    int height = (int)Math.Floor(tileSize.Height * devicePixelRatio);
                    using (var bitmap = TryConstructBitmap(width, height, PixelFormat.Format32bppArgb))
                    {
                        if (bitmap == null)
                        {
                            throw new HttpError(500, "Internal Server Error",
                                                $"Failed to allocate bitmap ({width}x{height}). Insufficient memory?");
                        }

                        if (transparent)
                        {
                            bitmap.MakeTransparent();
                        }

                        using (var g = System.Drawing.Graphics.FromImage(bitmap))
                        {
                            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

                            using (var graphics = new BitmapGraphics(g))
                            {
                                graphics.ScaleTransform((float)devicePixelRatio);
                                RenderToGraphics(ctx, transform, graphics);
                            }
                        }

                        BitmapResponse(context.Response, outputStream, ctx.Styles, bitmap, transparent ? ContentTypes.Image.Png : null);
                    }
                    #endregion
                }

                if (dataURI)
                {
                    string contentType = context.Response.ContentType;
                    context.Response.ContentType = ContentTypes.Text.Plain;
                    ms.Seek(0, SeekOrigin.Begin);

                    context.Response.Output.Write("data:");
                    context.Response.Output.Write(contentType);
                    context.Response.Output.Write(";base64,");
                    context.Response.Output.Flush();

                    System.Security.Cryptography.ICryptoTransform encoder = new System.Security.Cryptography.ToBase64Transform();
                    using (System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(context.Response.OutputStream, encoder, System.Security.Cryptography.CryptoStreamMode.Write))
                    {
                        ms.WriteTo(cs);
                        cs.FlushFinalBlock();
                    }
                }

                context.Response.Flush();
                context.Response.Close();
                return;
            }
Exemplo n.º 18
0
            public override void Process(ResourceManager resourceManager)
            {
                Selector   selector;
                RectangleF tileRect;
                MapOptions options = MapOptions.SectorGrid | MapOptions.SubsectorGrid | MapOptions.BordersMajor | MapOptions.BordersMinor | MapOptions.NamesMajor | MapOptions.NamesMinor | MapOptions.WorldsCapitals | MapOptions.WorldsHomeworlds;
                Style      style   = Style.Poster;

                ParseOptions(ref options, ref style);
                string title;
                bool   clipOutsectorBorders;

                if (HasOption("x1") && HasOption("x2") &&
                    HasOption("y1") && HasOption("y2"))
                {
                    // Arbitrary rectangle

                    int x1 = GetIntOption("x1", 0);
                    int x2 = GetIntOption("x2", 0);
                    int y1 = GetIntOption("y1", 0);
                    int y2 = GetIntOption("y2", 0);

                    tileRect = new RectangleF()
                    {
                        X = Math.Min(x1, x2),
                        Y = Math.Min(y1, y2)
                    };
                    tileRect.Width  = Math.Max(x1, x2) - tileRect.X;
                    tileRect.Height = Math.Max(y1, y2) - tileRect.Y;

                    // NOTE: This (re)initializes a static data structure used for
                    // resolving names into sector locations, so needs to be run
                    // before any other objects (e.g. Worlds) are loaded.
                    SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                    selector = new RectSelector(map, resourceManager, tileRect, slop: false);

                    // Include specified hexes
                    tileRect.Offset(-1, -1);
                    tileRect.Width  += 1;
                    tileRect.Height += 1;

                    title = $"Poster ({x1},{y1}) - ({x2},{y2})";
                    clipOutsectorBorders = true;
                }
                else if (HasOption("domain"))
                {
                    string domain = GetStringOption("domain");
                    double x, y, w = 2, h = 2;
                    switch (domain.ToLowerInvariant())
                    {
                    case "deneb": x = -4; y = -1; title = "Domain of Deneb"; break;

                    case "vland": x = -2; y = -1; title = "Domain of Vland"; break;

                    case "ilelish": x = -2; y = 1; title = "Domain of Ilelish"; break;

                    case "antares": x = 0; y = -2; title = "Domain of Antares"; break;

                    case "sylea": x = 0; y = 0; title = "Domain of Sylea"; break;

                    case "sol": x = 0; y = 2; title = "Domain of Sol"; break;

                    case "gateway": x = 2; y = 0; title = "Domain of Gateway"; break;

                    // And these aren't domains, but...
                    case "foreven": x = -6; y = -1; title = "Land Grant / Foreven"; break;

                    case "imperium": x = -4; y = -1; w = 7; h = 5; title = "Third Imperium"; break;

                    case "solomani": x = -1.5; y = 2.75; w = 4; h = 2.25; title = "Solomani Confederacy"; break;

                    case "zhodani": x = -8; y = -3; w = 5; h = 3; title = "Zhodani Consulate"; break;

                    case "hive":
                    case "hiver": x = 2; y = 1; w = 6; h = 4; title = "Hiver Federation"; break;

                    case "aslan": x = -8; y = 1; w = 7; h = 4; title = "Aslan Hierate"; break;

                    case "vargr": x = -4; y = -4; w = 8; h = 3; title = "Vargr Extents"; break;

                    case "kkree": x = 4; y = -2; w = 4; h = 4; title = "Two Thousand Worlds"; break;

                    case "jp": x = 0; y = -3; w = 4; h = 3; title = "Julian Protectorate"; break;
                    // TODO: Zhodani provinces

                    case "chartedspace": x = -8; y = -3; w = 16; h = 8; title = "Charted Space"; break;

                    case "jg": x = 160; y = 0; w = 2; h = 2; title = "Judges Guild"; break;

                    default:
                        throw new HttpError(404, "Not Found", $"Unknown domain: {domain}");
                    }

                    int x1 = (int)Math.Round(x * Astrometrics.SectorWidth - Astrometrics.ReferenceHex.X + 1);
                    int y1 = (int)Math.Round(y * Astrometrics.SectorHeight - Astrometrics.ReferenceHex.Y + 1);
                    int x2 = (int)Math.Round(x1 + w * Astrometrics.SectorWidth - 1);
                    int y2 = (int)Math.Round(y1 + h * Astrometrics.SectorHeight - 1);

                    tileRect = new RectangleF()
                    {
                        X = Math.Min(x1, x2),
                        Y = Math.Min(y1, y2)
                    };
                    tileRect.Width  = Math.Max(x1, x2) - tileRect.X;
                    tileRect.Height = Math.Max(y1, y2) - tileRect.Y;

                    // NOTE: This (re)initializes a static data structure used for
                    // resolving names into sector locations, so needs to be run
                    // before any other objects (e.g. Worlds) are loaded.
                    SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));
                    selector = new RectSelector(map, resourceManager, tileRect, slop: false);

                    // Include selected hexes
                    tileRect.Offset(-1, -1);
                    tileRect.Width  += 1;
                    tileRect.Height += 1;

                    // Account for jagged hexes
                    tileRect.Height += 0.5f;
                    tileRect.Inflate(0.25f, 0.10f);
                    if (style == Style.Candy)
                    {
                        tileRect.Width += 0.75f;
                    }

                    clipOutsectorBorders = true;
                }
                else
                {
                    // Sector - either POSTed or specified by name
                    Sector sector = null;
                    options &= ~MapOptions.SectorGrid;

                    if (Context.Request.HttpMethod == "POST")
                    {
                        bool lint = GetBoolOption("lint", defaultValue: false);
                        Func <ErrorLogger.Record, bool> filter = null;
                        if (lint)
                        {
                            bool hide_uwp = GetBoolOption("hide-uwp", defaultValue: false);
                            bool hide_tl  = GetBoolOption("hide-tl", defaultValue: false);
                            filter = (ErrorLogger.Record record) =>
                            {
                                if (hide_uwp && record.message.StartsWith("UWP"))
                                {
                                    return(false);
                                }
                                if (hide_tl && record.message.StartsWith("UWP: TL"))
                                {
                                    return(false);
                                }
                                return(true);
                            };
                        }
                        ErrorLogger errors = new ErrorLogger(filter);

                        sector = GetPostedSector(Context.Request, errors) ??
                                 throw new HttpError(400, "Bad Request", "Either file or data must be supplied in the POST data.");
                        if (lint && !errors.Empty)
                        {
                            throw new HttpError(400, "Bad Request", errors.ToString());
                        }


                        title = "User Data";

                        // TODO: Suppress all OTU rendering.
                        options &= ~(MapOptions.WorldsHomeworlds | MapOptions.WorldsCapitals);
                    }
                    else
                    {
                        string sectorName = GetStringOption("sector") ??
                                            throw new HttpError(400, "Bad Request", "No sector specified.");

                        SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu"));

                        sector = map.FromName(sectorName) ??
                                 throw new HttpError(404, "Not Found", $"The specified sector '{sectorName}' was not found.");

                        title = sector.Names[0].Text;
                    }

                    if (sector != null && HasOption("subsector") && GetStringOption("subsector").Length > 0)
                    {
                        string subsector = GetStringOption("subsector");
                        int    index     = sector.SubsectorIndexFor(subsector);
                        if (index == -1)
                        {
                            throw new HttpError(404, "Not Found", $"The specified subsector '{subsector}' was not found.");
                        }

                        selector = new SubsectorSelector(resourceManager, sector, index);

                        tileRect = sector.SubsectorBounds(index);

                        options &= ~(MapOptions.SectorGrid | MapOptions.SubsectorGrid);

                        title = $"{title} - Subsector {'A' + index}";
                    }
                    else if (sector != null && HasOption("quadrant") && GetStringOption("quadrant").Length > 0)
                    {
                        string quadrant = GetStringOption("quadrant");
                        int    index;
                        switch (quadrant.ToLowerInvariant())
                        {
                        case "alpha": index = 0; quadrant = "Alpha"; break;

                        case "beta": index = 1; quadrant = "Beta"; break;

                        case "gamma": index = 2; quadrant = "Gamma"; break;

                        case "delta": index = 3; quadrant = "Delta"; break;

                        default:
                            throw new HttpError(400, "Bad Request", $"The specified quadrant '{quadrant}' is invalid.");
                        }

                        selector = new QuadrantSelector(resourceManager, sector, index);
                        tileRect = sector.QuadrantBounds(index);

                        options &= ~(MapOptions.SectorGrid | MapOptions.SubsectorGrid | MapOptions.SectorsMask);

                        title = $"{title} - {quadrant} Quadrant";
                    }
                    else
                    {
                        selector = new SectorSelector(resourceManager, sector);
                        tileRect = sector.Bounds;

                        options &= ~(MapOptions.SectorGrid);
                    }

                    // Account for jagged hexes
                    tileRect.Height += 0.5f;
                    tileRect.Inflate(0.25f, 0.10f);
                    if (style == Style.Candy)
                    {
                        tileRect.Width += 0.75f;
                    }
                    clipOutsectorBorders = false;
                }

                const double NormalScale = 64; // pixels/parsec - standard subsector-rendering scale
                double       scale       = GetDoubleOption("scale", NormalScale).Clamp(MinScale, MaxScale);

                int  rot   = GetIntOption("rotation", 0) % 4;
                int  hrot  = GetIntOption("hrotation", 0);
                bool thumb = GetBoolOption("thumb", false);

                Stylesheet stylesheet = new Stylesheet(scale, options, style);

                Size tileSize = new Size((int)Math.Floor(tileRect.Width * scale * Astrometrics.ParsecScaleX), (int)Math.Floor(tileRect.Height * scale * Astrometrics.ParsecScaleY));

                if (thumb)
                {
                    tileSize.Width  = (int)Math.Floor(16 * tileSize.Width / scale);
                    tileSize.Height = (int)Math.Floor(16 * tileSize.Height / scale);
                    scale           = 16;
                }

                int            bitmapWidth = tileSize.Width, bitmapHeight = tileSize.Height;
                AbstractMatrix transform = AbstractMatrix.Identity;

                switch (rot)
                {
                case 1:     // 90 degrees clockwise
                    transform.RotatePrepend(90);
                    transform.TranslatePrepend(0, -bitmapHeight);
                    Util.Swap(ref bitmapWidth, ref bitmapHeight);
                    break;

                case 2:     // 180 degrees
                    transform.RotatePrepend(180);
                    transform.TranslatePrepend(-bitmapWidth, -bitmapHeight);
                    break;

                case 3:     // 270 degrees clockwise
                    transform.RotatePrepend(270);
                    transform.TranslatePrepend(-bitmapWidth, 0);
                    Util.Swap(ref bitmapWidth, ref bitmapHeight);
                    break;
                }

                // TODO: Figure out how to compose rot and hrot properly.
                Size bitmapSize = new Size(bitmapWidth, bitmapHeight);

                if (hrot != 0)
                {
                    ApplyHexRotation(hrot, stylesheet, ref bitmapSize, ref transform);
                }

                if (GetBoolOption("clampar", defaultValue: false))
                {
                    // Landscape: 1.91:1 (1.91)
                    // Portrait: 4:5 (0.8)
                    const double MIN_ASPECT_RATIO = 0.8;
                    const double MAX_ASPECT_RATIO = 1.91;
                    double       aspectRatio      = (double)bitmapSize.Width / (double)bitmapSize.Height;
                    Size         newSize          = bitmapSize;
                    if (aspectRatio < MIN_ASPECT_RATIO)
                    {
                        newSize.Width = (int)Math.Floor(bitmapSize.Height * MIN_ASPECT_RATIO);
                    }
                    else if (aspectRatio > MAX_ASPECT_RATIO)
                    {
                        newSize.Height = (int)Math.Floor(bitmapSize.Width / MAX_ASPECT_RATIO);
                    }
                    if (newSize != bitmapSize)
                    {
                        transform.TranslatePrepend(
                            (newSize.Width - bitmapSize.Width) / 2f,
                            (newSize.Height - bitmapSize.Height) / 2f);
                        bitmapSize = newSize;
                    }
                }

                RenderContext ctx = new RenderContext(resourceManager, selector, tileRect, scale, options, stylesheet, tileSize)
                {
                    ClipOutsectorBorders = clipOutsectorBorders
                };

                ProduceResponse(Context, title, ctx, bitmapSize, transform);
            }
 public void Unregister(AbstractMatrix <T> matrix)
 {
     matrix.Change -= ListenerMsg;
 }
Exemplo n.º 20
0
 private static void SumMatrix <T, U>(AbstractMatrix <T> a, AbstractMatrix <U> b, string message)
 {
     ShowMatrix(a.Sum(b), message);
 }
Exemplo n.º 21
0
 public void Unregister <T>(AbstractMatrix <T> matrix) where T : struct
 {
     matrix.PropertyChanged -= Message;
 }
 public int GetHashCode(AbstractMatrix <T> obj)
 {
     throw new NotImplementedException();
 }