Ejemplo n.º 1
0
        private static void DrawWorld(RenderContext ctx, FontCache styleRes, World world, WorldLayer layer)
        {
            bool isCapital = world.IsCapital;
            bool isHiPop = world.Population >= 1e9;
            bool renderName = ctx.styles.worldDetails.HasFlag(WorldDetails.AllNames) ||
                (ctx.styles.worldDetails.HasFlag(WorldDetails.KeyNames) && (isCapital || isHiPop));
            bool renderUWP = ctx.styles.worldDetails.HasFlag(WorldDetails.Uwp);

            using (RenderUtil.SaveState(ctx.graphics))
            {
                XPen pen = new XPen(XColor.Empty);
                XSolidBrush solidBrush = new XSolidBrush();

                ctx.graphics.SmoothingMode = XSmoothingMode.AntiAlias;

                // Center on the parsec
                PointF center = Astrometrics.HexToCenter(world.Coordinates);

                XMatrix matrix = new XMatrix();
                matrix.TranslatePrepend(center.X, center.Y);
                matrix.ScalePrepend(ctx.styles.hexContentScale / Astrometrics.ParsecScaleX, ctx.styles.hexContentScale / Astrometrics.ParsecScaleY);
                ctx.graphics.MultiplyTransform(matrix, XMatrixOrder.Prepend);

                if (!ctx.styles.useWorldImages)
                {
                    if (layer == WorldLayer.Background)
                    {
                        #region Zone
                        if (ctx.styles.worldDetails.HasFlag(WorldDetails.Zone))
                        {
                            if (world.IsAmber || world.IsRed || world.IsBlue)
                            {
                                PenInfo pi =
                                    world.IsAmber ? ctx.styles.amberZone.pen :
                                    world.IsRed ? ctx.styles.redZone.pen : ctx.styles.blueZone.pen;
                                pi.Apply(ref pen);

                                if (renderName && ctx.styles.fillMicroBorders)
                                {
                                    using (RenderUtil.SaveState(ctx.graphics))
                                    {
                                        ctx.graphics.IntersectClip(new RectangleF(-.5f, -.5f, 1f, renderUWP ? 0.65f : 0.75f));
                                        ctx.graphics.DrawEllipse(pen, -0.4f, -0.4f, 0.8f, 0.8f);
                                    }
                                }
                                else
                                {
                                    ctx.graphics.DrawEllipse(pen, -0.4f, -0.4f, 0.8f, 0.8f);
                                }
                            }
                        }
                        #endregion

                        #region Hex
                        if (ctx.styles.worldDetails.HasFlag(WorldDetails.Hex))
                        {
                            int coords;
                            switch (ctx.styles.hexCoordinateStyle)
                            {
                                default:
                                case Stylesheet.HexCoordinateStyle.Sector: coords = world.Hex; break;
                                case Stylesheet.HexCoordinateStyle.Subsector: coords = world.SubsectorHex; break;
                            }
                            String hex = coords.ToString("0000", CultureInfo.InvariantCulture);
                            XSize size = ctx.graphics.MeasureString(hex, ctx.styles.hexNumber.Font);
                            solidBrush.Color = ctx.styles.hexNumber.textColor;
                            ctx.graphics.DrawString(hex, ctx.styles.hexNumber.Font, solidBrush, 0.0f, -0.5f, RenderUtil.StringFormatTopCenter);
                        }
                        #endregion
                    }

                    if (layer == WorldLayer.Foreground)
                    {
                        #region Disc
                        if (ctx.styles.worldDetails.HasFlag(WorldDetails.Type))
                        {
                            // Blank out world area, so routes are shown correctly
                            if (!ctx.styles.fillMicroBorders)
                            {
                                solidBrush.Color = ctx.styles.backgroundColor;
                                ctx.graphics.DrawEllipse(solidBrush, -0.15f, -0.15f, 0.3f, 0.3f);
                            }

                            if (world.Size <= 0)
                            {
                                #region Asteroid-Belt
                                if (ctx.styles.worldDetails.HasFlag(WorldDetails.Asteroids))
                                {
                                    // Basic pattern, with probability varying per position:
                                    //   o o o
                                    //  o o o o
                                    //   o o o

                                    int[] lpx = { -2, 0, 2, -3, -1, 1, 3, -2, 0, 2 };
                                    int[] lpy = { -2, -2, -2, 0, 0, 0, 0, 2, 2, 2 };
                                    float[] lpr = { 0.5f, 0.9f, 0.5f, 0.6f, 0.9f, 0.9f, 0.6f, 0.5f, 0.9f, 0.5f };

                                    solidBrush.Color = ctx.styles.worlds.textColor;

                                    // Random generator is seeded with world location so it is always the same
                                    Random rand = new Random(world.Coordinates.X ^ world.Coordinates.Y);
                                    for (int i = 0; i < lpx.Length; ++i)
                                    {
                                        if (rand.NextDouble() < lpr[i])
                                        {
                                            float px = lpx[i] * 0.035f;
                                            float py = lpy[i] * 0.035f;

                                            float w = 0.04f + (float)rand.NextDouble() * 0.03f;
                                            float h = 0.04f + (float)rand.NextDouble() * 0.03f;

                                            // If necessary, add jitter here
                                            float dx = 0, dy = 0;

                                            ctx.graphics.DrawEllipse(solidBrush,
                                                px + dx - w / 2, py + dy - h / 2, w, h);
                                        }
                                    }
                                }
                                else
                                {
                                    // Just a glyph
                                    solidBrush.Color = ctx.styles.worlds.textColor;
                                    RenderUtil.DrawGlyph(ctx.graphics, Glyph.DiamondX, styleRes, solidBrush, 0.0f, 0.0f);
                                }
                                #endregion
                            }
                            else
                            {
                                XColor penColor, brushColor;
                                ctx.styles.WorldColors(world, out penColor, out brushColor);

                                if (!brushColor.IsEmpty)
                                {
                                    solidBrush.Color = brushColor;
                                    ctx.graphics.DrawEllipse(solidBrush, -0.1f, -0.1f, 0.2f, 0.2f);
                                }

                                if (!penColor.IsEmpty)
                                {
                                    ctx.styles.worldWater.pen.Apply(ref pen);
                                    pen.Color = penColor;
                                    ctx.graphics.DrawEllipse(pen, -0.1f, -0.1f, 0.2f, 0.2f);
                                }
                            }
                        }
                        else
                        {
                            // Dotmap
                            solidBrush.Color = ctx.styles.worlds.textColor;
                            ctx.graphics.DrawEllipse(solidBrush, -0.2f, -0.2f, 0.4f, 0.4f);
                        }
                        #endregion

                        #region GasGiant
                        if (ctx.styles.worldDetails.HasFlag(WorldDetails.GasGiant))
                        {
                            if (world.GasGiants > 0)
                            {
                                solidBrush.Color = ctx.styles.worlds.textColor;
                                RenderUtil.DrawGlyph(ctx.graphics, Glyph.Circle, styleRes, solidBrush, ctx.styles.GasGiantPosition.X, ctx.styles.GasGiantPosition.Y);
                            }
                        }
                        #endregion

                        #region Name
                        if (renderName)
                        {
                            string name = world.Name;
                            if (isHiPop)
                                name = name.ToUpperInvariant();

                            Color textColor = isCapital ? ctx.styles.worlds.textHighlightColor : ctx.styles.worlds.textColor;

                            if (ctx.styles.worlds.textStyle.Uppercase)
                                name = name.ToUpper();

                            DrawWorldLabel(ctx, ctx.styles.worlds.textBackgroundStyle, solidBrush, textColor, ctx.styles.worlds.textStyle.Translation, ctx.styles.worlds.Font, name);
                        }
                        #endregion

                        #region Starport
                        if (ctx.styles.worldDetails.HasFlag(WorldDetails.Starport))
                        {
                            string starport = world.Starport.ToString();
                            DrawWorldLabel(ctx, ctx.styles.worlds.textBackgroundStyle, solidBrush, ctx.styles.worlds.textColor, ctx.styles.StarportPosition, styleRes.StarportFont, starport);
                        }
                        #endregion

                        #region UWP
                        if (renderUWP)
                        {
                            string uwp = world.UWP;
                            solidBrush.Color = ctx.styles.worlds.textColor;

                            ctx.graphics.DrawString(uwp, ctx.styles.hexNumber.Font, solidBrush, ctx.styles.StarportPosition.X, -ctx.styles.StarportPosition.Y, RenderUtil.StringFormatCentered);
                        }
                        #endregion

                        #region Allegiance
                        // TODO: Mask off background for allegiance
                        if (ctx.styles.worldDetails.HasFlag(WorldDetails.Allegiance))
                        {
                            if (!world.HasDefaultAllegiance())
                            {
                                string alleg = world.Allegiance;
                                solidBrush.Color = ctx.styles.worlds.textColor;

                                if (ctx.styles.lowerCaseAllegiance)
                                    alleg = alleg.ToLowerInvariant();

                                ctx.graphics.DrawString(alleg, ctx.styles.worlds.SmallFont, solidBrush, ctx.styles.AllegiancePosition.X, ctx.styles.AllegiancePosition.Y, RenderUtil.StringFormatCentered);
                            }
                        }
                        #endregion

                        #region Bases
                        // TODO: Mask off background for glyphs
                        if (ctx.styles.worldDetails.HasFlag(WorldDetails.Bases))
                        {
                            int num_bases = world.Bases.Length;

                            // Base 1
                            bool bottomUsed = false;
                            if (num_bases > 0)
                            {
                                Glyph glyph = Glyph.FromBaseCode(world.BaseAllegiance, world.Bases[0]);
                                if (glyph.Printable)
                                {
                                    PointF pt = ctx.styles.BaseTopPosition;
                                    if (glyph.Bias == Glyph.GlyphBias.Bottom)
                                    {
                                        pt = ctx.styles.BaseBottomPosition;
                                        bottomUsed = true;
                                    }

                                    solidBrush.Color = glyph.IsHighlighted ? ctx.styles.worlds.textHighlightColor : ctx.styles.worlds.textColor;
                                    RenderUtil.DrawGlyph(ctx.graphics, glyph, styleRes, solidBrush, pt.X, pt.Y);
                                }
                            }

                            // Base 2
                            if (num_bases > 1)
                            {
                                Glyph glyph = Glyph.FromBaseCode(world.Allegiance, world.Bases[1]);
                                if (glyph.Printable)
                                {
                                    PointF pt = bottomUsed ? ctx.styles.BaseTopPosition : ctx.styles.BaseBottomPosition;
                                    solidBrush.Color = glyph.IsHighlighted ? ctx.styles.worlds.textHighlightColor : ctx.styles.worlds.textColor;
                                    RenderUtil.DrawGlyph(ctx.graphics, glyph, styleRes, solidBrush, pt.X, pt.Y);
                                }
                            }

                            // Research Stations
                            string rs;
                            if ((rs = world.ResearchStation) != null)
                            {
                                Glyph glyph = Glyph.FromResearchCode(rs);
                                solidBrush.Color = glyph.IsHighlighted ? ctx.styles.worlds.textHighlightColor : ctx.styles.worlds.textColor;
                                RenderUtil.DrawGlyph(ctx.graphics, glyph, styleRes, solidBrush, ctx.styles.BaseMiddlePosition.X, ctx.styles.BaseMiddlePosition.Y);
                            }
                            else if (world.IsReserve)
                            {
                                Glyph glyph = Glyph.Reserve;
                                solidBrush.Color = glyph.IsHighlighted ? ctx.styles.worlds.textHighlightColor : ctx.styles.worlds.textColor;
                                RenderUtil.DrawGlyph(ctx.graphics, glyph, styleRes, solidBrush, ctx.styles.BaseMiddlePosition.X, 0);
                            }
                            else if (world.IsPenalColony)
                            {
                                Glyph glyph = Glyph.Prison;
                                solidBrush.Color = glyph.IsHighlighted ? ctx.styles.worlds.textHighlightColor : ctx.styles.worlds.textColor;
                                RenderUtil.DrawGlyph(ctx.graphics, glyph, styleRes, solidBrush, ctx.styles.BaseMiddlePosition.X, 0);
                            }
                            else if (world.IsPrisonExileCamp)
                            {
                                Glyph glyph = Glyph.ExileCamp;
                                solidBrush.Color = glyph.IsHighlighted ? ctx.styles.worlds.textHighlightColor : ctx.styles.worlds.textColor;
                                RenderUtil.DrawGlyph(ctx.graphics, glyph, styleRes, solidBrush, ctx.styles.BaseMiddlePosition.X, 0);
                            }
                        }
                        #endregion
                    }

                }
                else
                {
                    float imageRadius = ((world.Size <= 0) ? 0.6f : (0.3f * (world.Size / 5.0f + 0.2f))) / 2;
                    float decorationRadius = imageRadius;

                    if (layer == WorldLayer.Background)
                    {
                        #region Disc
                        if (ctx.styles.worldDetails.HasFlag(WorldDetails.Type))
                        {
                            if (world.Size <= 0)
                            {
                                const float scaleX = 1.5f;
                                const float scaleY = 1.0f;
                                XImage img = s_worldImages["Belt"];

                                lock (img)
                                {
                                    ctx.graphics.DrawImage(img, -imageRadius * scaleX, -imageRadius * scaleY, imageRadius * 2 * scaleX, imageRadius * 2 * scaleY);
                                }
                            }
                            else
                            {
                                XImage img;
                                switch (world.Hydrographics)
                                {
                                    default:
                                    case 0x0: img = s_worldImages["Hyd0"]; break;
                                    case 0x1: img = s_worldImages["Hyd1"]; break;
                                    case 0x2: img = s_worldImages["Hyd2"]; break;
                                    case 0x3: img = s_worldImages["Hyd3"]; break;
                                    case 0x4: img = s_worldImages["Hyd4"]; break;
                                    case 0x5: img = s_worldImages["Hyd5"]; break;
                                    case 0x6: img = s_worldImages["Hyd6"]; break;
                                    case 0x7: img = s_worldImages["Hyd7"]; break;
                                    case 0x8: img = s_worldImages["Hyd8"]; break;
                                    case 0x9: img = s_worldImages["Hyd9"]; break;
                                    case 0xA: img = s_worldImages["HydA"]; break;
                                }
                                if (img != null)
                                {
                                    lock (img)
                                    {
                                        ctx.graphics.DrawImage(img, -imageRadius, -imageRadius, imageRadius * 2, imageRadius * 2);
                                    }
                                }
                            }
                        }
                        else
                        {
                            // Dotmap
                            solidBrush.Color = ctx.styles.worlds.textColor;
                            ctx.graphics.DrawEllipse(solidBrush, -0.2f, -0.2f, 0.4f, 0.4f);
                        }
                        #endregion
                    }

                    if (layer == WorldLayer.Foreground)
                    {
                        #region Zone
                        if (ctx.styles.worldDetails.HasFlag(WorldDetails.Zone))
                        {
                            if (world.IsAmber || world.IsRed || world.IsBlue)
                            {
                                PenInfo pi =
                                    world.IsAmber ? ctx.styles.amberZone.pen :
                                    world.IsRed ? ctx.styles.redZone.pen : ctx.styles.blueZone.pen;
                                pi.Apply(ref pen);

                                // TODO: Try and accomplish this using dash pattern
                                decorationRadius += 0.1f;
                                ctx.graphics.DrawArc(pen, -decorationRadius, -decorationRadius, decorationRadius * 2, decorationRadius * 2, 5, 80);
                                ctx.graphics.DrawArc(pen, -decorationRadius, -decorationRadius, decorationRadius * 2, decorationRadius * 2, 95, 80);
                                ctx.graphics.DrawArc(pen, -decorationRadius, -decorationRadius, decorationRadius * 2, decorationRadius * 2, 185, 80);
                                ctx.graphics.DrawArc(pen, -decorationRadius, -decorationRadius, decorationRadius * 2, decorationRadius * 2, 275, 80);
                            }
                        }
                        #endregion

                        #region GasGiant
                        if (ctx.styles.worldDetails.HasFlag(WorldDetails.GasGiant))
                        {
                            if (world.GasGiants > 0)
                            {
                                decorationRadius += 0.1f;
                                const float symbolRadius = 0.05f;
                                solidBrush.Color = ctx.styles.worlds.textHighlightColor; ;
                                ctx.graphics.DrawEllipse(solidBrush, decorationRadius - symbolRadius, 0.0f - symbolRadius, symbolRadius * 2, symbolRadius * 2);
                            }
                        }
                        #endregion

                        #region UWP
                        if (renderUWP)
                        {
                            string uwp = world.UWP;
                            solidBrush.Color = ctx.styles.worlds.textColor;

                            using (RenderUtil.SaveState(ctx.graphics))
                            {
                                XMatrix uwpMatrix = new XMatrix();
                                uwpMatrix.TranslatePrepend(decorationRadius, 0.0f);
                                uwpMatrix.ScalePrepend(ctx.styles.worlds.textStyle.Scale.Width, ctx.styles.worlds.textStyle.Scale.Height);
                                uwpMatrix.Multiply(uwpMatrix, XMatrixOrder.Prepend);
                                ctx.graphics.DrawString(uwp, ctx.styles.hexNumber.Font, solidBrush, ctx.styles.StarportPosition.X, -ctx.styles.StarportPosition.Y, RenderUtil.StringFormatCenterLeft);
                            }
                        }
                        #endregion

                        #region Name
                        if (renderName)
                        {
                            string name = world.Name;
                            if (isHiPop)
                                name = name.ToUpperInvariant();

                            using (RenderUtil.SaveState(ctx.graphics))
                            {
                                Color textColor = isCapital ? ctx.styles.worlds.textHighlightColor : ctx.styles.worlds.textColor;

                                if (ctx.styles.worlds.textStyle.Uppercase)
                                    name = name.ToUpper();

                                decorationRadius += 0.1f;
                                XMatrix imageMatrix = new XMatrix();
                                imageMatrix.TranslatePrepend(decorationRadius, 0.0f);
                                imageMatrix.ScalePrepend(ctx.styles.worlds.textStyle.Scale.Width, ctx.styles.worlds.textStyle.Scale.Height);
                                imageMatrix.TranslatePrepend(ctx.graphics.MeasureString(name, ctx.styles.worlds.Font).Width / 2, 0.0f); // Left align
                                ctx.graphics.MultiplyTransform(imageMatrix, XMatrixOrder.Prepend);

                                DrawWorldLabel(ctx, ctx.styles.worlds.textBackgroundStyle, solidBrush, textColor, ctx.styles.worlds.textStyle.Translation, ctx.styles.worlds.Font, name);
                            }
                        }
                        #endregion
                    }
                }
            }
        }