private static void DrawWorld(RenderContext ctx, FontCache styleRes, World world, WorldLayer layer) { bool isPlaceholder = world.IsPlaceholder; bool isCapital = world.IsCapital; bool isHiPop = world.IsHi; 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)) { Stylesheet.StyleElement? maybeElem = ZoneStyle(ctx, world); if (maybeElem.HasValue) { Stylesheet.StyleElement elem = maybeElem.Value; if (!elem.fillColor.IsEmpty) { solidBrush.Color = elem.fillColor; ctx.graphics.DrawEllipse(solidBrush, -0.4f, -0.4f, 0.8f, 0.8f); } PenInfo pi = elem.pen; if (!pi.color.IsEmpty) { 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.numberAllHexes && ctx.styles.worldDetails.HasFlag(WorldDetails.Hex)) { string hex; switch (ctx.styles.hexCoordinateStyle) { default: case Stylesheet.HexCoordinateStyle.Sector: hex = world.Hex; break; case Stylesheet.HexCoordinateStyle.Subsector: hex = world.SubsectorHex; break; } 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) { Stylesheet.StyleElement? elem = ZoneStyle(ctx, world); TextBackgroundStyle worldTextBackgroundStyle = (elem.HasValue && !elem.Value.fillColor.IsEmpty) ? TextBackgroundStyle.None : ctx.styles.worlds.textBackgroundStyle; #region Name if (renderName) { string name = world.Name; if ((isHiPop && ctx.styles.worldDetails.HasFlag(WorldDetails.Highlight)) || ctx.styles.worlds.textStyle.Uppercase) name = name.ToUpperInvariant(); Color textColor = (isCapital && ctx.styles.worldDetails.HasFlag(WorldDetails.Highlight)) ? ctx.styles.worlds.textHighlightColor : ctx.styles.worlds.textColor; XFont font = ((isHiPop || isCapital) && ctx.styles.worldDetails.HasFlag(WorldDetails.Highlight)) ? ctx.styles.worlds.LargeFont : ctx.styles.worlds.Font; DrawWorldLabel(ctx, worldTextBackgroundStyle, solidBrush, textColor, ctx.styles.worlds.textStyle.Translation, font, name); } #endregion #region Allegiance // TODO: Mask off background for allegiance if (ctx.styles.worldDetails.HasFlag(WorldDetails.Allegiance)) { string alleg = world.Allegiance; if (!SecondSurvey.IsDefaultAllegiance(alleg)) { if (!ctx.styles.t5AllegianceCodes && alleg.Length > 2) alleg = SecondSurvey.T5AllegianceCodeToLegacyCode(alleg); 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 if (!isPlaceholder) { #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 Starport if (ctx.styles.worldDetails.HasFlag(WorldDetails.Starport)) { string starport = world.Starport.ToString(); DrawWorldLabel(ctx, worldTextBackgroundStyle, 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 Bases // TODO: Mask off background for glyphs if (ctx.styles.worldDetails.HasFlag(WorldDetails.Bases)) { string bases = world.Bases; // Special case: Show Zho Naval+Military as diamond if (world.BaseAllegiance == "Zh" && bases == "KM") bases = "Z"; // Base 1 bool bottomUsed = false; if (bases.Length > 0) { Glyph glyph = Glyph.FromBaseCode(world.BaseAllegiance, 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 (bases.Length > 1) { Glyph glyph = Glyph.FromBaseCode(world.LegacyAllegiance, 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 } #region Disc if (ctx.styles.worldDetails.HasFlag(WorldDetails.Type)) { if (isPlaceholder) { DrawWorldLabel(ctx, ctx.styles.placeholder.textBackgroundStyle, solidBrush, ctx.styles.placeholder.textColor, ctx.styles.placeholder.position, ctx.styles.placeholder.Font, ctx.styles.placeholder.content); } else { 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 } } else // ctx.styles.useWorldImages { 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 (isPlaceholder) { DrawWorldLabel(ctx, ctx.styles.placeholder.textBackgroundStyle, solidBrush, ctx.styles.placeholder.textColor, ctx.styles.placeholder.position, ctx.styles.placeholder.Font, ctx.styles.placeholder.content); } else 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 (isPlaceholder) return; 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.worldDetails.HasFlag(WorldDetails.Highlight)) ? 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 } } } }
/// <summary> /// Some test code to check that there are no typing errors in the formulars. /// </summary> public static void Test() { XMatrix xm1 = new XMatrix(23, -35, 837, 332, -3, 12); Matrix m1 = new Matrix(23, -35, 837, 332, -3, 12); DumpMatrix(xm1, m1); XMatrix xm2 = new XMatrix(12, 235, 245, 42, 33, -56); Matrix m2 = xm2.ToMatrix(); DumpMatrix(xm2, m2); // xm1.Multiply(xm2, XMatrixOrder.Prepend); // m1.Multiply(m2, MatrixOrder.Append); xm1.Multiply(xm2, XMatrixOrder.Append); m1.Multiply(m2, MatrixOrder.Append); DumpMatrix(xm1, m1); xm1.Translate(-243, 342, XMatrixOrder.Append); m1.Translate(-243, 342, MatrixOrder.Append); DumpMatrix(xm1, m1); xm1.Scale(-5.66, 7.87); m1.Scale(-5.66f, 7.87f); // xm1.Scale(-5.66, 7.87, XMatrixOrder.Prepend); // m1.Scale(-5.66f, 7.87f, MatrixOrder.Prepend); DumpMatrix(xm1, m1); xm1.Rotate(135, XMatrixOrder.Append); m1.Rotate(135, MatrixOrder.Append); // xm1.Scale(-5.66, 7.87, XMatrixOrder.Prepend); // m1.Scale(-5.66f, 7.87f, MatrixOrder.Prepend); DumpMatrix(xm1, m1); xm1.RotateAt(177, new XPoint(-3456, 654), XMatrixOrder.Append); m1.RotateAt(177, new PointF(-3456, 654), MatrixOrder.Append); DumpMatrix(xm1, m1); xm1.Shear(0.76, -0.87, XMatrixOrder.Prepend); m1.Shear(0.76f, -0.87f, MatrixOrder.Prepend); DumpMatrix(xm1, m1); xm1 = new XMatrix(23, -35, 837, 332, -3, 12); m1 = new Matrix(23, -35, 837, 332, -3, 12); XPoint[] xpoints = new XPoint[3]{new XPoint(23, 10), new XPoint(-27, 120), new XPoint(-87, -55)}; PointF[] points = new PointF[3]{new PointF(23, 10), new PointF(-27, 120), new PointF(-87, -55)}; xm1.TransformPoints(xpoints); m1.TransformPoints(points); xm1.Invert(); m1.Invert(); DumpMatrix(xm1, m1); }