public Stylesheet(double scale, MapOptions options, Style style) { float onePixel = 1f / (float)scale; grayscale = false; lightBackground = false; subsectorGrid.visible = ((scale >= SubsectorsMinScale) && options.HasFlag(MapOptions.SubsectorGrid)); sectorGrid.visible = ((scale >= SectorGridMinScale) && options.HasFlag(MapOptions.SectorGrid)); parsecGrid.visible = (scale >= ParsecMinScale); showSomeSectorNames = ((scale >= SectorNameMinScale) && (scale <= SectorNameMaxScale) && ((options & MapOptions.SectorsMask) != 0)); showAllSectorNames = showSomeSectorNames && ((scale >= SectorNameAllSelectedScale) || options.HasFlag(MapOptions.SectorsAll)); subsectorNames.visible = ((scale >= SubsectorNameMinScale) && (scale <= SubsectorNameMaxScale) && ((options & MapOptions.SectorsMask) != 0)); worlds.visible = (scale >= WorldMinScale); pseudoRandomStars.visible = (PseudoRandomStarsMinScale <= scale) && (scale <= PseudoRandomStarsMaxScale); showRiftOverlay = (scale <= PseudoRandomStarsMaxScale || style == Style.Candy); t5AllegianceCodes = scale >= T5AllegianceCodeMinScale; riftOpacity = ScaleInterpolate(0f, 0.85f, scale, 1 / 4f, 4f); deepBackgroundOpacity = ScaleInterpolate(1f, 0f, scale, 1 / 8f, 2f); macroRoutes.visible = (scale >= MacroRouteMinScale) && (scale <= MacroRouteMaxScale); macroNames.visible = (scale >= MacroLabelMinScale) && (scale <= MacroLabelMaxScale); megaNames.visible = scale <= MegaLabelMaxScale && ((options & MapOptions.NamesMask) != 0); showMicroNames = ((scale >= MicroNameMinScale) && ((options & MapOptions.NamesMask) != 0)); capitals.visible = (scale >= MacroWorldsMinScale) && (scale <= MacroWorldsMaxScale); hexStyle = (((options & MapOptions.ForceHexes) == 0) && (scale < ParsecHexMinScale)) ? HexStyle.Square : HexStyle.Hex; microBorderStyle = hexStyle == HexStyle.Square ? MicroBorderStyle.Square : MicroBorderStyle.Hex; macroBorders.visible = (scale >= MacroBorderMinScale) && (scale < MicroBorderMinScale) && ((options & MapOptions.BordersMask) != 0); microBorders.visible = (scale >= MicroBorderMinScale) && ((options & MapOptions.BordersMask) != 0); fillMicroBorders = microBorders.visible && options.HasFlag(MapOptions.FilledBorders); microRoutes.visible = (scale >= RouteMinScale); worldDetails = !worlds.visible ? WorldDetails.None : (scale < WorldBasicMinScale) ? WorldDetails.Dotmap : (scale < WorldFullMinScale) ? WorldDetails.Atlas : WorldDetails.Poster; showWorldDetailColors = worldDetails == WorldDetails.Poster && options.HasFlag(MapOptions.WorldColors); lowerCaseAllegiance = (scale < WorldFullMinScale); worlds.textBackgroundStyle = TextBackgroundStyle.Rectangle; hexCoordinateStyle = HexCoordinateStyle.Sector; numberAllHexes = false; if (scale < WorldFullMinScale) { // Atlas-style const float x = 0.225f; const float y = 0.125f; BaseTopPosition.X = -x; BaseTopPosition.Y = -y; BaseBottomPosition.X = -x; BaseBottomPosition.Y = y; GasGiantPosition.X = x; GasGiantPosition.Y = -y; AllegiancePosition.X = x; AllegiancePosition.Y = y; BaseMiddlePosition.X = options.HasFlag(MapOptions.ForceHexes) ? -0.35f : -0.2f; BaseMiddlePosition.Y = 0; StarportPosition.X = 0.0f; StarportPosition.Y = -0.24f; worlds.position.X = 0.0f; worlds.position.Y = 0.4f; } else { // Poster-style const float x = 0.25f; const float y = 0.18f; BaseTopPosition.X = -x; BaseTopPosition.Y = -y; BaseBottomPosition.X = -x; BaseBottomPosition.Y = y; GasGiantPosition.X = x; GasGiantPosition.Y = -y; AllegiancePosition.X = x; AllegiancePosition.Y = y; BaseMiddlePosition.X = -0.35f; BaseMiddlePosition.Y = 0f; StarportPosition.X = 0f; StarportPosition.Y = -0.225f; worlds.position.X = 0.0f; worlds.position.Y = 0.37f; // Don't hide hex bottom, leave room for UWP } if (scale >= WorldUwpMinScale) { worldDetails |= WorldDetails.Uwp; BaseBottomPosition.Y = 0.1f; BaseMiddlePosition.Y = (BaseBottomPosition.Y + BaseTopPosition.Y) / 2; AllegiancePosition.Y = 0.1f; } if (worlds.visible) { float fontScale = (scale <= 96f || style == Style.Candy) ? 1f : 96f / Math.Min((float)scale, 192f); worlds.fontInfo = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.2f : 0.15f * fontScale, FontStyle.Bold); wingdingFont = new FontInfo("Wingdings", scale < WorldFullMinScale ? 0.2f : 0.175f * fontScale); glyphFont = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.175f : 0.15f * fontScale, FontStyle.Bold); hexNumber.fontInfo = new FontInfo(DEFAULT_FONT, 0.1f * fontScale); worlds.smallFontInfo = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.2f : 0.1f * fontScale, FontStyle.Regular); worlds.largeFontInfo = worlds.fontInfo; starportFont = (scale < WorldFullMinScale) ? worlds.smallFontInfo : worlds.fontInfo; } sectorName.fontInfo = new FontInfo(DEFAULT_FONT, 5.5f); subsectorNames.fontInfo = new FontInfo(DEFAULT_FONT, 1.5f); float overlayFontSize = Math.Max(onePixel * 12f, 0.375f); droyneWorlds.fontInfo = new FontInfo(DEFAULT_FONT, overlayFontSize); ancientsWorlds.fontInfo = new FontInfo(DEFAULT_FONT, overlayFontSize); minorHomeWorlds.fontInfo = new FontInfo(DEFAULT_FONT, overlayFontSize); droyneWorlds.content = "\u2605\u2606"; // BLACK STAR / WHITE STAR minorHomeWorlds.content = "\u273B"; // TEARDROP-SPOKED ASTERISK ancientsWorlds.content = "\u2600"; // BLACK SUN WITH RAYS microBorders.fontInfo = new FontInfo(DEFAULT_FONT, (scale == MicroNameMinScale) ? 0.6f : 0.25f, FontStyle.Bold); microBorders.smallFontInfo = new FontInfo(DEFAULT_FONT, 0.15f, FontStyle.Bold); microBorders.largeFontInfo = new FontInfo(DEFAULT_FONT, 0.75f, FontStyle.Bold); macroNames.fontInfo = new FontInfo(DEFAULT_FONT, 8f / 1.4f, FontStyle.Bold); macroNames.smallFontInfo = new FontInfo(DEFAULT_FONT, 5f / 1.4f, FontStyle.Regular); macroNames.mediumFontInfo = new FontInfo(DEFAULT_FONT, 6.5f / 1.4f, FontStyle.Italic); float megaNameScaleFactor = Math.Min(35f, 0.75f * onePixel); megaNames.fontInfo = new FontInfo(DEFAULT_FONT, 24f * megaNameScaleFactor, FontStyle.Bold); megaNames.mediumFontInfo = new FontInfo(DEFAULT_FONT, 22f * megaNameScaleFactor, FontStyle.Regular); megaNames.smallFontInfo = new FontInfo(DEFAULT_FONT, 18f * megaNameScaleFactor, FontStyle.Italic); capitals.fillColor = Color.Wheat; capitals.textColor = Color.Red; blueZone.pen.color = Color.Blue; amberZone.pen.color = Color.Gold; redZone.pen.color = Color.Red; macroBorders.pen.color = Color.Red; macroRoutes.pen.color = Color.White; microBorders.pen.color = Color.Gray; Color gridColor = Color.FromArgb(ScaleInterpolate(0, 255, scale, SectorGridMinScale, SectorGridFullScale), Color.Gray); microRoutes.pen.color = Color.Gray; Color foregroundColor = Color.White; backgroundColor = Color.Black; Color lightColor = Color.LightGray; Color darkColor = Color.DarkGray; Color dimColor = Color.DimGray; Color highlightColor = Color.Red; microBorders.textColor = Color.Gold; worldWater.fillColor = Color.DeepSkyBlue; worldNoWater.fillColor = Color.White; worldNoWater.pen.color = Color.Empty; parsecGrid.pen = new PenInfo(gridColor, onePixel); subsectorGrid.pen = new PenInfo(gridColor, onePixel * 2); sectorGrid.pen = new PenInfo(gridColor, (subsectorGrid.visible ? 4 : 2) * onePixel); worldWater.pen = new PenInfo(Color.Empty, Math.Max(0.01f, onePixel)); microBorders.textStyle.Rotation = 0; microBorders.textStyle.Translation = new PointF(0, 0); microBorders.textStyle.Scale = new SizeF(1.0f, 1.0f); microBorders.textStyle.Uppercase = false; sectorName.textStyle.Rotation = -50; // degrees sectorName.textStyle.Translation = new PointF(0, 0); sectorName.textStyle.Scale = new SizeF(0.75f, 1.0f); sectorName.textStyle.Uppercase = false; sectorName.textStyle.Wrap = true; subsectorNames.textStyle = sectorName.textStyle; worlds.textStyle.Rotation = 0; worlds.textStyle.Scale = new SizeF(1.0f, 1.0f); worlds.textStyle.Translation = worlds.position; worlds.textStyle.Uppercase = false; showNebulaBackground = false; showGalaxyBackground = deepBackgroundOpacity > 0.0f; useWorldImages = false; // Cap pen widths when zooming in float penScale = (scale <= 64) ? 1f : (64f / (float)scale); float borderPenWidth = (scale < MicroBorderMinScale) ? 1 : // When rendering vector borders (scale < ParsecMinScale) ? 1 : // When not rendering "hexes" 0.16f * penScale; // ... but cut in half by clipping float routePenWidth = scale <= 16 ? 0.2f : 0.08f * penScale; microBorders.pen.width = borderPenWidth; macroBorders.pen.width = borderPenWidth; microRoutes.pen.width = routePenWidth; amberZone.pen.width = redZone.pen.width = blueZone.pen.width = 0.05f * penScale; macroRoutes.pen.width = borderPenWidth; macroRoutes.pen.dashStyle = DashStyle.Dash; populationOverlay.fillColor = Color.FromArgb(0x80, 0xff, 0xff, 0x00); importanceOverlay.fillColor = Color.FromArgb(0x20, 0x80, 0xff, 0x00); highlightWorlds.fillColor = Color.FromArgb(0x80, 0xff, 0x00, 0x00); populationOverlay.pen = new PenInfo(Color.Empty, 0.03f * penScale, DashStyle.Dash); importanceOverlay.pen = new PenInfo(Color.Empty, 0.03f * penScale, DashStyle.Dot); highlightWorlds.pen = new PenInfo(Color.Empty, 0.03f * penScale, DashStyle.DashDot); switch (style) { case Style.Poster: { // This is the default - no changes break; } case Style.Atlas: { grayscale = true; lightBackground = true; capitals.fillColor = Color.DarkGray; capitals.textColor = Color.Black; amberZone.pen.color = Color.LightGray; blueZone.pen.color = Color.Gray; // TODO: make dashed redZone.pen.color = Color.Black; macroBorders.pen.color = Color.Black; macroRoutes.pen.color = Color.Gray; microBorders.pen.color = Color.Black; microRoutes.pen.color = Color.Gray; foregroundColor = Color.Black; backgroundColor = Color.White; lightColor = Color.DarkGray; darkColor = Color.DarkGray; dimColor = Color.LightGray; highlightColor = Color.Gray; microBorders.textColor = Color.Gray; worldWater.fillColor = Color.Black; worldNoWater.fillColor = Color.Empty; worldNoWater.fillColor = Color.White; worldNoWater.pen = new PenInfo(Color.Black, onePixel); riftOpacity = Math.Min(riftOpacity, 0.70f); showWorldDetailColors = false; populationOverlay.fillColor = Color.FromArgb(0x40, highlightColor); populationOverlay.pen.color = Color.Gray; importanceOverlay.fillColor = Color.FromArgb(0x20, highlightColor); importanceOverlay.pen.color = Color.Gray; highlightWorlds.fillColor = Color.FromArgb(0x30, highlightColor); highlightWorlds.pen.color = Color.Gray; break; } case Style.FASA: { showGalaxyBackground = false; deepBackgroundOpacity = 0f; riftOpacity = 0; Color inkColor = Color.FromArgb(0x5C, 0x40, 0x33); foregroundColor = inkColor; backgroundColor = Color.White; grayscale = true; // TODO: Tweak to be "monochrome" lightBackground = true; capitals.fillColor = inkColor; capitals.textColor = inkColor; amberZone.pen.color = inkColor; amberZone.pen.width = onePixel * 2; blueZone.pen.color = inkColor; // TODO: make dashed redZone.pen.color = Color.Empty; redZone.fillColor = Color.FromArgb(0x80, inkColor); macroBorders.pen.color = inkColor; macroRoutes.pen.color = inkColor; microBorders.pen.color = inkColor; microBorders.pen.width = onePixel * 2; microBorders.fontInfo.size *= 0.6f; microBorders.fontInfo.style = FontStyle.Regular; microRoutes.pen.color = inkColor; lightColor = Color.FromArgb(0x80, inkColor); darkColor = inkColor; dimColor = inkColor; highlightColor = inkColor; microBorders.textColor = inkColor; hexStyle = HexStyle.Hex; microBorderStyle = MicroBorderStyle.Curve; parsecGrid.pen.color = lightColor; sectorGrid.pen.color = lightColor; subsectorGrid.pen.color = lightColor; worldWater.fillColor = inkColor; worldNoWater.fillColor = inkColor; worldWater.pen.color = Color.Empty; worldNoWater.pen.color = Color.Empty; showWorldDetailColors = false; worldDetails = worldDetails & ~WorldDetails.Starport; worldDetails = worldDetails & ~WorldDetails.Allegiance; worldDetails = worldDetails & ~WorldDetails.Bases; worldDetails = worldDetails & ~WorldDetails.GasGiant; worldDetails = worldDetails & ~WorldDetails.Highlight; worldDetails = worldDetails & ~WorldDetails.Uwp; worlds.fontInfo.size *= 0.85f; worlds.textStyle.Translation = new PointF(0, 0.25f); numberAllHexes = true; hexCoordinateStyle = HexCoordinateStyle.Subsector; overrideLineStyle = LineStyle.Solid; populationOverlay.fillColor = Color.FromArgb(0x40, highlightColor); populationOverlay.pen.color = Color.Gray; importanceOverlay.fillColor = Color.FromArgb(0x20, highlightColor); importanceOverlay.pen.color = Color.Gray; highlightWorlds.fillColor = Color.FromArgb(0x30, highlightColor); highlightWorlds.pen.color = Color.Gray; break; } case Style.Print: { lightBackground = true; foregroundColor = Color.Black; backgroundColor = Color.White; lightColor = Color.DarkGray; darkColor = Color.DarkGray; dimColor = Color.LightGray; microRoutes.pen.color = Color.Gray; microBorders.textColor = Color.Brown; amberZone.pen.color = Color.Gold; worldNoWater.fillColor = Color.White; worldNoWater.pen = new PenInfo(Color.Black, onePixel); riftOpacity = Math.Min(riftOpacity, 0.70f); populationOverlay.fillColor = Color.FromArgb(0x40, populationOverlay.fillColor); populationOverlay.pen.color = Color.Gray; importanceOverlay.fillColor = Color.FromArgb(0x20, importanceOverlay.fillColor); importanceOverlay.pen.color = Color.Gray; highlightWorlds.fillColor = Color.FromArgb(0x30, highlightWorlds.fillColor); highlightWorlds.pen.color = Color.Gray; break; } case Style.Draft: { int inkOpacity = 0xB0; showGalaxyBackground = false; lightBackground = true; deepBackgroundOpacity = 0f; backgroundColor = Color.AntiqueWhite; foregroundColor = Color.FromArgb(inkOpacity, Color.Black); highlightColor = Color.FromArgb(inkOpacity, Color.Red); lightColor = Color.FromArgb(inkOpacity, Color.DarkCyan); darkColor = Color.FromArgb(inkOpacity, Color.Black); dimColor = Color.FromArgb(inkOpacity / 2, Color.Black); subsectorGrid.pen.color = Color.FromArgb(inkOpacity, Color.Firebrick); const string FONT_NAME = "Comic Sans MS"; worlds.fontInfo.name = FONT_NAME; worlds.smallFontInfo.name = FONT_NAME; starportFont.name = FONT_NAME; worlds.largeFontInfo.name = FONT_NAME; worlds.largeFontInfo.size = worlds.fontInfo.size * 1.25f; worlds.fontInfo.size *= 0.8f; macroNames.fontInfo.name = FONT_NAME; macroNames.mediumFontInfo.name = FONT_NAME; macroNames.smallFontInfo.name = FONT_NAME; megaNames.fontInfo.name = FONT_NAME; megaNames.mediumFontInfo.name = FONT_NAME; megaNames.smallFontInfo.name = FONT_NAME; microBorders.smallFontInfo.name = FONT_NAME; microBorders.largeFontInfo.name = FONT_NAME; microBorders.fontInfo.name = FONT_NAME; macroBorders.fontInfo.name = FONT_NAME; macroRoutes.fontInfo.name = FONT_NAME; capitals.fontInfo.name = FONT_NAME; macroBorders.smallFontInfo.name = FONT_NAME; microBorders.textStyle.Uppercase = true; sectorName.textStyle.Uppercase = true; subsectorNames.textStyle.Uppercase = true; // TODO: Render small, around edges subsectorNames.visible = false; worlds.textStyle.Uppercase = true; // TODO: Decide on this. It's nice to not overwrite the parsec grid, but // it looks very cluttered, especially amber/red zones. worlds.textBackgroundStyle = TextBackgroundStyle.None; worldDetails = worldDetails & ~WorldDetails.Allegiance; subsectorNames.fontInfo.name = FONT_NAME; sectorName.fontInfo.name = FONT_NAME; worlds.largeFontInfo.style |= FontStyle.Underline; microBorders.pen.width = onePixel * 4; microBorders.pen.dashStyle = DashStyle.Dot; worldNoWater.fillColor = foregroundColor; worldWater.fillColor = Color.Empty; worldWater.pen = new PenInfo(foregroundColor, onePixel * 2); amberZone.pen.color = foregroundColor; amberZone.pen.width = onePixel; redZone.pen.width = onePixel * 2; microRoutes.pen.color = Color.Gray; parsecGrid.pen.color = lightColor; microBorders.textColor = Color.FromArgb(inkOpacity, Color.Brown); riftOpacity = Math.Min(riftOpacity, 0.30f); numberAllHexes = true; populationOverlay.fillColor = Color.FromArgb(0x40, populationOverlay.fillColor); populationOverlay.pen.color = Color.Gray; importanceOverlay.fillColor = Color.FromArgb(0x20, importanceOverlay.fillColor); importanceOverlay.pen.color = Color.Gray; highlightWorlds.fillColor = Color.FromArgb(0x30, highlightWorlds.fillColor); highlightWorlds.pen.color = Color.Gray; break; } case Style.Candy: { useWorldImages = true; pseudoRandomStars.visible = false; showNebulaBackground = deepBackgroundOpacity < 0.5f; hexStyle = HexStyle.None; microBorderStyle = MicroBorderStyle.Curve; sectorGrid.visible = sectorGrid.visible && (scale >= 4); subsectorGrid.visible = subsectorGrid.visible && (scale >= 32); parsecGrid.visible = false; subsectorGrid.pen.width = 0.03f * (64.0f / (float)scale); subsectorGrid.pen.dashStyle = DashStyle.Custom; subsectorGrid.pen.dashPattern = new float[] { 10.0f, 8.0f }; sectorGrid.pen.width = 0.03f * (64.0f / (float)scale); sectorGrid.pen.dashStyle = DashStyle.Custom; sectorGrid.pen.dashPattern = new float[] { 10.0f, 8.0f }; worlds.textBackgroundStyle = TextBackgroundStyle.Shadow; worldDetails = worldDetails & ~WorldDetails.Starport & ~WorldDetails.Allegiance & ~WorldDetails.Bases & ~WorldDetails.Hex; if (scale < CandyMinWorldNameScale) { worldDetails = worldDetails & ~WorldDetails.KeyNames & ~WorldDetails.AllNames; } if (scale < CandyMinUwpScale) { worldDetails = worldDetails & ~WorldDetails.Uwp; } amberZone.pen.color = Color.Goldenrod; sectorName.textStyle.Rotation = 0; sectorName.textStyle.Translation = new PointF(0, -0.25f); sectorName.textStyle.Scale = new SizeF(0.5f, 0.25f); sectorName.textStyle.Uppercase = true; subsectorNames.textStyle.Rotation = 0; subsectorNames.textStyle.Translation = new PointF(0, -0.25f); subsectorNames.textStyle.Scale = new SizeF(0.3f, 0.15f); // Expand subsectorNames.textStyle.Uppercase = true; microBorders.textStyle.Rotation = 0; microBorders.textStyle.Translation = new PointF(0, 0.25f); microBorders.textStyle.Scale = new SizeF(1.0f, 0.5f); // Expand microBorders.textStyle.Uppercase = true; microBorders.pen.color = Color.FromArgb(128, Color.Red); worlds.textStyle.Rotation = 0; worlds.textStyle.Scale = new SizeF(1f, 0.5f); // Expand worlds.textStyle.Translation = new PointF(0, 0); worlds.textStyle.Uppercase = true; if (scale > CandyMaxWorldRelativeScale) { hexContentScale = CandyMaxWorldRelativeScale / (float)scale; } break; } } sectorName.textColor = scale < 16 ? foregroundColor : scale < 48 ? darkColor : dimColor; subsectorNames.textColor = scale < 16 ? foregroundColor : scale < 48 ? darkColor : dimColor; if (style == Style.Candy) { subsectorNames.textColor = sectorName.textColor = Color.FromArgb(128, Color.Goldenrod); amberZone.pen.width = redZone.pen.width = blueZone.pen.width = 0.035f; microRoutes.pen.width = scale < CandyMaxRouteRelativeScale ? routePenWidth : routePenWidth / 2; macroBorders.pen.width = scale < CandyMaxBorderRelativeScale ? borderPenWidth : borderPenWidth / 4; microBorders.pen.width = scale < CandyMaxBorderRelativeScale ? borderPenWidth : borderPenWidth / 4; } preferredMimeType = (style == Style.Candy) ? System.Net.Mime.MediaTypeNames.Image.Jpeg : Util.MediaTypeName_Image_Png; pseudoRandomStars.fillColor = foregroundColor; droyneWorlds.textColor = minorHomeWorlds.textColor = ancientsWorlds.textColor = microBorders.textColor; megaNames.textColor = foregroundColor; megaNames.textHighlightColor = highlightColor; macroNames.textColor = foregroundColor; macroNames.textHighlightColor = highlightColor; macroRoutes.textColor = foregroundColor; macroRoutes.textHighlightColor = highlightColor; worlds.textColor = foregroundColor; worlds.textHighlightColor = highlightColor; hexNumber.textColor = lightColor; imageBorderColor = lightColor; placeholder.content = "*"; placeholder.fontInfo = new FontInfo("Georgia", 0.6f); placeholder.textColor = foregroundColor; placeholder.position = new PointF(0, 0.17f); }
private const float WorldUwpMinScale = 96; // Above this: UWP shown above name #endregion Fields #region Constructors public Stylesheet(double scale, MapOptions options, Style style) { float onePixel = 1f / (float)scale; grayscale = false; lightBackground = false; subsectorGrid.visible = ((scale >= SubsectorsMinScale) && options.HasFlag(MapOptions.SubsectorGrid)); sectorGrid.visible = ((scale >= SectorGridMinScale) && options.HasFlag(MapOptions.SectorGrid)); parsecGrid.visible = (scale >= ParsecMinScale); showSomeSectorNames = ((scale >= SectorNameMinScale) && (scale <= SectorNameMaxScale) && ((options & MapOptions.SectorsMask) != 0)); showAllSectorNames = showSomeSectorNames && ((scale >= SectorNameAllSelectedScale) || options.HasFlag(MapOptions.SectorsAll)); subsectorNames.visible = ((scale >= SubsectorNameMinScale) && (scale <= SubsectorNameMaxScale) && ((options & MapOptions.SectorsMask) != 0)); worlds.visible = (scale >= WorldMinScale); pseudoRandomStars.visible = (PseudoRandomStarsMinScale <= scale) && (scale <= PseudoRandomStarsMaxScale); showRifts = (scale <= PseudoRandomStarsMaxScale || style == Style.Candy); t5AllegianceCodes = scale >= T5AllegianceCodeMinScale; float logscale = (float)Math.Log(scale, 2.0); riftOpacity = ScaleInterpolate(0f, 0.85f, scale, 1/4f, 4f); deepBackgroundOpacity = ScaleInterpolate(1f, 0f, scale, 1/8f, 2f); macroRoutes.visible = (scale >= MacroRouteMinScale) && (scale <= MacroRouteMaxScale); macroNames.visible = (scale >= MacroLabelMinScale) && (scale <= MacroLabelMaxScale); megaNames.visible = scale <= MegaLabelMaxScale && ((options & MapOptions.NamesMask) != 0); showMicroNames = ((scale >= MicroNameMinScale) && ((options & MapOptions.NamesMask) != 0)); capitals.visible = (scale >= MacroWorldsMinScale) && (scale <= MacroWorldsMaxScale); hexStyle = (((options & MapOptions.ForceHexes) == 0) && (scale < ParsecHexMinScale)) ? HexStyle.Square : HexStyle.Hex; microBorderStyle = hexStyle == HexStyle.Square ? MicroBorderStyle.Square : MicroBorderStyle.Hex; macroBorders.visible = (scale >= MacroBorderMinScale) && (scale < MicroBorderMinScale) && ((options & MapOptions.BordersMask) != 0); microBorders.visible = (scale >= MicroBorderMinScale) && ((options & MapOptions.BordersMask) != 0); fillMicroBorders = microBorders.visible && options.HasFlag(MapOptions.FilledBorders); microRoutes.visible = (scale >= RouteMinScale); worldDetails = !worlds.visible ? WorldDetails.None : (scale < WorldBasicMinScale) ? WorldDetails.Dotmap : (scale < WorldFullMinScale) ? WorldDetails.Atlas : WorldDetails.Poster; showWorldDetailColors = worldDetails == WorldDetails.Poster && options.HasFlag(MapOptions.WorldColors); lowerCaseAllegiance = (scale < WorldFullMinScale); worlds.textBackgroundStyle = TextBackgroundStyle.Rectangle; hexCoordinateStyle = HexCoordinateStyle.Sector; numberAllHexes = false; if (scale < WorldFullMinScale) { // Atlas-style const float x = 0.225f; const float y = 0.125f; BaseTopPosition.X = -x; BaseTopPosition.Y = -y; BaseBottomPosition.X = -x; BaseBottomPosition.Y = y; GasGiantPosition.X = x; GasGiantPosition.Y = -y; AllegiancePosition.X = x; AllegiancePosition.Y = y; BaseMiddlePosition.X = options.HasFlag(MapOptions.ForceHexes) ? -0.35f : -0.2f; BaseMiddlePosition.Y = 0; StarportPosition.X = 0.0f; StarportPosition.Y = -0.24f; worlds.position.X = 0.0f; worlds.position.Y = 0.4f; } else { // Poster-style const float x = 0.25f; const float y = 0.18f; BaseTopPosition.X = -x; BaseTopPosition.Y = -y; BaseBottomPosition.X = -x; BaseBottomPosition.Y = y; GasGiantPosition.X = x; GasGiantPosition.Y = -y; AllegiancePosition.X = x; AllegiancePosition.Y = y; BaseMiddlePosition.X = -0.35f; BaseMiddlePosition.Y = 0f; StarportPosition.X = 0f; StarportPosition.Y = -0.225f; worlds.position.X = 0.0f; worlds.position.Y = 0.37f; // Don't hide hex bottom, leave room for UWP } if (scale >= WorldUwpMinScale) { worldDetails |= WorldDetails.Uwp; BaseBottomPosition.Y = 0.1f; BaseMiddlePosition.Y = (BaseBottomPosition.Y + BaseTopPosition.Y) / 2; AllegiancePosition.Y = 0.1f; } if (worlds.visible) { float fontScale = (scale <= 96f || style == Style.Candy) ? 1f : 96f / Math.Min((float)scale, 192f); worlds.fontInfo = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.2f : 0.15f * fontScale, XFontStyle.Bold); wingdingFont = new FontInfo("Wingdings", scale < WorldFullMinScale ? 0.2f : 0.175f * fontScale); glyphFont = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.175f : 0.15f * fontScale, XFontStyle.Bold); hexNumber.fontInfo = new FontInfo(DEFAULT_FONT, 0.1f * fontScale); worlds.smallFontInfo = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.2f : 0.1f * fontScale, XFontStyle.Regular); worlds.largeFontInfo = worlds.fontInfo; starportFont = (scale < WorldFullMinScale) ? worlds.smallFontInfo : worlds.fontInfo; } sectorName.fontInfo = new FontInfo(DEFAULT_FONT, 5.5f); subsectorNames.fontInfo = new FontInfo(DEFAULT_FONT, 1.5f); microBorders.fontInfo = new FontInfo(DEFAULT_FONT, (scale == MicroNameMinScale) ? 0.6f : 0.25f, XFontStyle.Bold); microBorders.smallFontInfo = new FontInfo(DEFAULT_FONT, 0.15f, XFontStyle.Bold); microBorders.largeFontInfo = new FontInfo(DEFAULT_FONT, 0.75f, XFontStyle.Bold); macroNames.fontInfo = new FontInfo(DEFAULT_FONT, 8f / 1.4f, XFontStyle.Bold); macroNames.smallFontInfo = new FontInfo(DEFAULT_FONT, 5f / 1.4f, XFontStyle.Regular); macroNames.mediumFontInfo = new FontInfo(DEFAULT_FONT, 6.5f / 1.4f, XFontStyle.Italic); float megaNameScaleFactor = 1.0f * onePixel; megaNames.fontInfo = new FontInfo(DEFAULT_FONT, 24f * megaNameScaleFactor, XFontStyle.Bold); megaNames.mediumFontInfo = new FontInfo(DEFAULT_FONT, 22f * megaNameScaleFactor, XFontStyle.Regular); megaNames.smallFontInfo = new FontInfo(DEFAULT_FONT, 20f * megaNameScaleFactor, XFontStyle.Italic); capitals.fillColor = Color.Wheat; capitals.textColor = Color.Red; blueZone.pen.color = Color.Blue; amberZone.pen.color = Color.Gold; redZone.pen.color = Color.Red; macroBorders.pen.color = Color.Red; macroRoutes.pen.color = Color.White; microBorders.pen.color = Color.Gray; Color gridColor = Color.FromArgb(ScaleInterpolate(0, 255, scale, SectorGridMinScale, SectorGridFullScale), Color.Gray); microRoutes.pen.color = Color.Gray; Color foregroundColor = Color.White; backgroundColor = Color.Black; Color lightColor = Color.LightGray; Color darkColor = Color.DarkGray; Color dimColor = Color.DimGray; Color highlightColor = Color.Red; microBorders.textColor = Color.Gold; worldWater.fillColor = Color.DeepSkyBlue; worldNoWater.fillColor = Color.White; worldNoWater.pen.color = Color.Empty; parsecGrid.pen = new PenInfo(gridColor, onePixel); subsectorGrid.pen = new PenInfo(gridColor, onePixel * 2); sectorGrid.pen = new PenInfo(gridColor, (subsectorGrid.visible ? 4 : 2) * onePixel); worldWater.pen = new PenInfo(Color.Empty, Math.Max(0.01f, onePixel)); microBorders.textStyle.Rotation = 0; microBorders.textStyle.Translation = new PointF(0, 0); microBorders.textStyle.Scale = new SizeF(1.0f, 1.0f); microBorders.textStyle.Uppercase = false; sectorName.textStyle.Rotation = -50; // degrees sectorName.textStyle.Translation = new PointF(0, 0); sectorName.textStyle.Scale = new SizeF(0.75f, 1.0f); sectorName.textStyle.Uppercase = false; sectorName.textStyle.Wrap = true; subsectorNames.textStyle = sectorName.textStyle; worlds.textStyle.Rotation = 0; worlds.textStyle.Scale = new SizeF(1.0f, 1.0f); worlds.textStyle.Translation = worlds.position; worlds.textStyle.Uppercase = false; useBackgroundImage = false; useGalaxyImage = deepBackgroundOpacity > 0.0f; useWorldImages = false; // Cap pen widths when zooming in float penScale = (scale <= 64) ? 1f : (64f / (float)scale); float borderPenWidth = (scale < MicroBorderMinScale) ? 1 : // When rendering vector borders (scale < ParsecMinScale) ? 1 : // When not rendering "hexes" 0.16f * penScale; // ... but cut in half by clipping float routePenWidth = scale <= 16 ? 0.2f : 0.08f * penScale; microBorders.pen.width = borderPenWidth; macroBorders.pen.width = borderPenWidth; microRoutes.pen.width = routePenWidth; amberZone.pen.width = redZone.pen.width = blueZone.pen.width = 0.05f * penScale; macroRoutes.pen.width = borderPenWidth; macroRoutes.pen.DashStyle = XDashStyle.Dash; switch (style) { case Style.Poster: { // This is the default - no changes break; } case Style.Atlas: { grayscale = true; lightBackground = true; capitals.fillColor = Color.DarkGray; capitals.textColor = Color.Black; amberZone.pen.color = Color.LightGray; blueZone.pen.color = Color.Gray; // TODO: make dashed redZone.pen.color = Color.Black; macroBorders.pen.color = Color.Black; macroRoutes.pen.color = Color.Gray; microBorders.pen.color = Color.Black; microRoutes.pen.color = Color.Gray; foregroundColor = Color.Black; backgroundColor = Color.White; lightColor = Color.DarkGray; darkColor = Color.DarkGray; dimColor = Color.LightGray; highlightColor = Color.Gray; microBorders.textColor = Color.Gray; worldWater.fillColor = Color.Black; worldNoWater.fillColor = Color.Empty; worldNoWater.fillColor = Color.White; worldNoWater.pen = new PenInfo(Color.Black, onePixel); riftOpacity = Math.Min(riftOpacity, 0.70f); showWorldDetailColors = false; break; } case Style.FASA: { useGalaxyImage = false; deepBackgroundOpacity = 0f; riftOpacity = 0; Color inkColor = Color.FromArgb(0x5C, 0x40, 0x33); foregroundColor = inkColor; backgroundColor = Color.White; grayscale = true; // TODO: Tweak to be "monochrome" lightBackground = true; capitals.fillColor = inkColor; capitals.textColor = inkColor; amberZone.pen.color = inkColor; amberZone.pen.width = onePixel * 2; blueZone.pen.color = inkColor; // TODO: make dashed redZone.pen.color = Color.Empty; redZone.fillColor = Color.FromArgb(0x80, inkColor); macroBorders.pen.color = inkColor; macroRoutes.pen.color = inkColor; microBorders.pen.color = inkColor; microBorders.pen.width = onePixel * 2; microBorders.fontInfo.size *= 0.6f; microBorders.fontInfo.style = XFontStyle.Regular; microRoutes.pen.color = inkColor; lightColor = Color.FromArgb(0x80, inkColor); darkColor = inkColor; dimColor = inkColor; highlightColor = inkColor; microBorders.textColor = inkColor; hexStyle = HexStyle.Hex; microBorderStyle = MicroBorderStyle.Curve; parsecGrid.pen.color = lightColor; sectorGrid.pen.color = lightColor; subsectorGrid.pen.color = lightColor; worldWater.fillColor = inkColor; worldNoWater.fillColor = inkColor; worldWater.pen.color = Color.Empty; worldNoWater.pen.color = Color.Empty; showWorldDetailColors = false; worldDetails = worldDetails & ~WorldDetails.Starport; worldDetails = worldDetails & ~WorldDetails.Allegiance; worldDetails = worldDetails & ~WorldDetails.Bases; worldDetails = worldDetails & ~WorldDetails.GasGiant; worldDetails = worldDetails & ~WorldDetails.Highlight; worlds.fontInfo.size *= 0.85f; worlds.textStyle.Translation = new PointF(0, 0.25f); numberAllHexes = true; hexCoordinateStyle = HexCoordinateStyle.Subsector; overrideLineStyle = LineStyle.Solid; break; } case Style.Print: { lightBackground = true; foregroundColor = Color.Black; backgroundColor = Color.White; lightColor = Color.DarkGray; darkColor = Color.DarkGray; dimColor = Color.LightGray; microRoutes.pen.color = Color.Gray; microBorders.textColor = Color.Brown; amberZone.pen.color = Color.Gold; worldNoWater.fillColor = Color.White; worldNoWater.pen = new PenInfo(Color.Black, onePixel); riftOpacity = Math.Min(riftOpacity, 0.70f); break; } case Style.Draft: { int inkOpacity = 0xB0; useGalaxyImage = false; lightBackground = true; deepBackgroundOpacity = 0f; backgroundColor = Color.AntiqueWhite; foregroundColor = Color.FromArgb(inkOpacity, Color.Black); highlightColor = Color.FromArgb(inkOpacity, Color.Red); lightColor = Color.FromArgb(inkOpacity, Color.DarkCyan); darkColor = Color.FromArgb(inkOpacity, Color.Black); dimColor = Color.FromArgb(inkOpacity / 2, Color.Black); subsectorGrid.pen.color = Color.FromArgb(inkOpacity, Color.Firebrick); const string FONT_NAME = "Comic Sans MS"; worlds.fontInfo.name = FONT_NAME; worlds.smallFontInfo.name = FONT_NAME; starportFont.name = FONT_NAME; worlds.largeFontInfo.name = FONT_NAME; worlds.largeFontInfo.size = worlds.fontInfo.size * 1.25f; worlds.fontInfo.size *= 0.8f; macroNames.fontInfo.name = FONT_NAME; macroNames.mediumFontInfo.name = FONT_NAME; macroNames.smallFontInfo.name = FONT_NAME; megaNames.fontInfo.name = FONT_NAME; megaNames.mediumFontInfo.name = FONT_NAME; megaNames.smallFontInfo.name = FONT_NAME; microBorders.smallFontInfo.name = FONT_NAME; microBorders.largeFontInfo.name = FONT_NAME; microBorders.fontInfo.name = FONT_NAME; macroBorders.fontInfo.name = FONT_NAME; macroRoutes.fontInfo.name = FONT_NAME; capitals.fontInfo.name = FONT_NAME; macroBorders.smallFontInfo.name = FONT_NAME; microBorders.textStyle.Uppercase = true; sectorName.textStyle.Uppercase = true; subsectorNames.textStyle.Uppercase = true; // TODO: Render small, around edges subsectorNames.visible = false; worlds.textStyle.Uppercase = true; // TODO: Decide on this. It's nice to not overwrite the parsec grid, but // it looks very cluttered, especially amber/red zones. worlds.textBackgroundStyle = TextBackgroundStyle.None; worldDetails = worldDetails & ~WorldDetails.Allegiance; subsectorNames.fontInfo.name = FONT_NAME; sectorName.fontInfo.name = FONT_NAME; worlds.largeFontInfo.style |= XFontStyle.Underline; microBorders.pen.width = onePixel * 4; microBorders.pen.dashStyle = XDashStyle.Dot; worldNoWater.fillColor = foregroundColor; worldWater.fillColor = Color.Empty; worldWater.pen = new PenInfo(foregroundColor, onePixel * 2); amberZone.pen.color = foregroundColor; amberZone.pen.width = onePixel; redZone.pen.width = onePixel * 2; microRoutes.pen.color = Color.Gray; parsecGrid.pen.color = lightColor; microBorders.textColor = Color.FromArgb(inkOpacity, Color.Brown); riftOpacity = Math.Min(riftOpacity, 0.30f); numberAllHexes = true; break; } case Style.Candy: { useWorldImages = true; pseudoRandomStars.visible = false; useBackgroundImage = deepBackgroundOpacity < 0.5f; hexStyle = HexStyle.None; microBorderStyle = MicroBorderStyle.Curve; sectorGrid.visible = sectorGrid.visible && (scale >= 4); subsectorGrid.visible = subsectorGrid.visible && (scale >= 32); parsecGrid.visible = false; subsectorGrid.pen.width = 0.03f * (64.0f / (float)scale); subsectorGrid.pen.DashPattern = new double[] { 10.0, 8.0 }; sectorGrid.pen.width = 0.03f * (64.0f / (float)scale); sectorGrid.pen.DashPattern = new double[] { 10.0, 8.0 }; worlds.textBackgroundStyle = TextBackgroundStyle.Shadow; worldDetails = worldDetails & ~WorldDetails.Starport & ~WorldDetails.Allegiance & ~WorldDetails.Bases & ~WorldDetails.Hex; if (scale < CandyMinWorldNameScale) worldDetails = worldDetails & ~WorldDetails.KeyNames & ~WorldDetails.AllNames; if (scale < CandyMinUwpScale) worldDetails = worldDetails & ~WorldDetails.Uwp; amberZone.pen.color = Color.Goldenrod; sectorName.textStyle.Rotation = 0; sectorName.textStyle.Translation = new PointF(0, -0.25f); sectorName.textStyle.Scale = new SizeF(0.5f, 0.25f); sectorName.textStyle.Uppercase = true; subsectorNames.textStyle.Rotation = 0; subsectorNames.textStyle.Translation = new PointF(0, -0.25f); subsectorNames.textStyle.Scale = new SizeF(0.3f, 0.15f); // Expand subsectorNames.textStyle.Uppercase = true; microBorders.textStyle.Rotation = 0; microBorders.textStyle.Translation = new PointF(0, 0.25f); microBorders.textStyle.Scale = new SizeF(1.0f, 0.5f); // Expand microBorders.textStyle.Uppercase = true; microBorders.pen.color = Color.FromArgb(128, Color.Red); worlds.textStyle.Rotation = 0; worlds.textStyle.Scale = new SizeF(1f, 0.5f); // Expand worlds.textStyle.Translation = new PointF(0, 0); worlds.textStyle.Uppercase = true; if (scale > CandyMaxWorldRelativeScale) hexContentScale = CandyMaxWorldRelativeScale / (float)scale; break; } } sectorName.textColor = scale < 16 ? foregroundColor : scale < 48 ? darkColor : dimColor; subsectorNames.textColor = scale < 16 ? foregroundColor : scale < 48 ? darkColor : dimColor; if (style == Style.Candy) { subsectorNames.textColor = sectorName.textColor = Color.FromArgb(128, Color.Goldenrod); amberZone.pen.width = redZone.pen.width = blueZone.pen.width = 0.035f; microRoutes.pen.width = scale < CandyMaxRouteRelativeScale ? routePenWidth : routePenWidth / 2; macroBorders.pen.width = scale < CandyMaxBorderRelativeScale ? borderPenWidth : borderPenWidth / 4; microBorders.pen.width = scale < CandyMaxBorderRelativeScale ? borderPenWidth : borderPenWidth / 4; } preferredMimeType = (style == Style.Candy) ? System.Net.Mime.MediaTypeNames.Image.Jpeg : Util.MediaTypeName_Image_Png; pseudoRandomStars.fillColor = foregroundColor; megaNames.textColor = foregroundColor; megaNames.textHighlightColor = highlightColor; macroNames.textColor = foregroundColor; macroNames.textHighlightColor = highlightColor; macroRoutes.textColor = foregroundColor; macroRoutes.textHighlightColor = highlightColor; worlds.textColor = foregroundColor; worlds.textHighlightColor = highlightColor; hexNumber.textColor = lightColor; imageBorderColor = lightColor; placeholder.content = "*"; placeholder.fontInfo = new FontInfo("Georgia", 0.6f); placeholder.textColor = foregroundColor; placeholder.position = new PointF(0, 0.17f); }
public Stylesheet(double scale, MapOptions options, Style style) { grayscale = false; subsectorGrid.visible = ((scale >= SubsectorsMinScale) && options.HasFlag(MapOptions.SubsectorGrid)); sectorGrid.visible = ((scale >= SectorGridMinScale) && options.HasFlag(MapOptions.SectorGrid)); parsecGrid.visible = (scale >= ParsecMinScale); showSomeSectorNames = ((scale >= SectorNameMinScale) && (scale <= SectorNameMaxScale) && ((options & MapOptions.SectorsMask) != 0)); showAllSectorNames = showSomeSectorNames && ((scale >= SectorNameAllSelectedScale) || options.HasFlag(MapOptions.SectorsAll)); subsectorNames.visible = ((scale >= SubsectorNameMinScale) && (scale <= SubsectorNameMaxScale) && ((options & MapOptions.SectorsMask) != 0)); worlds.visible = (scale >= WorldMinScale); pseudoRandomStars.visible = (PseudoRandomStarsMinScale <= scale) && (scale <= PseudoRandomStarsMaxScale); showRifts = (scale <= PseudoRandomStarsMaxScale || style == Style.Candy); float logscale = (float)Math.Log(scale, 2.0); riftOpacity = Util.Clamp((logscale - -2f) / (2f - -2f), 0.0f, 1.0f) * 0.85f; deepBackgroundOpacity = 1.0f - Util.Clamp((logscale - -3f) / (0f - -3f), 0f, 1f); macroRoutes.visible = (scale >= MacroRouteMinScale) && (scale <= MacroRouteMaxScale); macroNames.visible = (scale >= MacroLabelMinScale) && (scale <= MacroLabelMaxScale); showMicroNames = ((scale >= MicroNameMinScale) && ((options & MapOptions.NamesMask) != 0)); capitals.visible = (scale >= MacroWorldsMinScale) && (scale <= MacroWorldsMaxScale); microBorderStyle = (((options & MapOptions.ForceHexes) == 0) && (scale < ParsecHexMinScale)) ? MicroBorderStyle.Square : MicroBorderStyle.Hex; macroBorders.visible = (scale >= MacroBorderMinScale) && (scale < MicroBorderMinScale) && ((options & MapOptions.BordersMask) != 0); microBorders.visible = (scale >= MicroBorderMinScale) && ((options & MapOptions.BordersMask) != 0); fillMicroBorders = microBorders.visible && options.HasFlag(MapOptions.FilledBorders); microRoutes.visible = (scale >= RouteMinScale); worldDetails = !worlds.visible ? 0 : (scale < WorldBasicMinScale) ? WorldDetails.Dotmap : (scale < WorldFullMinScale) ? WorldDetails.Atlas : WorldDetails.Poster; showWorldDetailColors = worldDetails == WorldDetails.Poster && options.HasFlag(MapOptions.WorldColors); lowerCaseAllegiance = (scale < WorldFullMinScale); worlds.textBackgroundStyle = TextBackgroundStyle.Rectangle; hexCoordinateStyle = HexCoordinateStyle.Sector; if (scale < WorldFullMinScale) { // Atlas-style const float x = 0.225f; const float y = 0.125f; BaseTopPosition.X = -x; BaseTopPosition.Y = -y; BaseBottomPosition.X = -x; BaseBottomPosition.Y = y; GasGiantPosition.X = x; GasGiantPosition.Y = -y; AllegiancePosition.X = x; AllegiancePosition.Y = y; BaseMiddlePosition.X = options.HasFlag(MapOptions.ForceHexes) ? -0.35f : -0.2f; BaseMiddlePosition.Y = 0; StarportPosition.X = 0.0f; StarportPosition.Y = -0.24f; worlds.position.X = 0.0f; worlds.position.Y = 0.4f; } else { // Poster-style const float x = 0.25f; const float y = 0.18f; BaseTopPosition.X = -x; BaseTopPosition.Y = -y; BaseBottomPosition.X = -x; BaseBottomPosition.Y = y; GasGiantPosition.X = x; GasGiantPosition.Y = -y; AllegiancePosition.X = x; AllegiancePosition.Y = y; BaseMiddlePosition.X = -0.35f; BaseMiddlePosition.Y = 0f; StarportPosition.X = 0f; StarportPosition.Y = -0.225f; worlds.position.X = 0.0f; worlds.position.Y = 0.37f; // Don't hide hex bottom, leave room for UWP } if (scale >= WorldUwpMinScale) { worldDetails |= WorldDetails.Uwp; BaseBottomPosition.Y = 0.1f; BaseMiddlePosition.Y = (BaseBottomPosition.Y + BaseTopPosition.Y) / 2; AllegiancePosition.Y = 0.1f; } if (worlds.visible) { float fontScale = (scale <= 96f || style == Style.Candy) ? 1f : 96f / (float)scale; worlds.fontInfo = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.2f : 0.15f * fontScale, XFontStyle.Bold); wingdingFont = new FontInfo("Wingdings", scale < WorldFullMinScale ? 0.2f : 0.175f * fontScale); glyphFont = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.175f : 0.15f * fontScale, XFontStyle.Bold); hexNumber.fontInfo = new FontInfo(DEFAULT_FONT, 0.1f * fontScale); worlds.smallFontInfo = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.2f : 0.1f * fontScale, XFontStyle.Regular); starportFont = (scale < WorldFullMinScale) ? worlds.smallFontInfo : worlds.fontInfo; } sectorName.fontInfo = new FontInfo(DEFAULT_FONT, 5.5f); subsectorNames.fontInfo = new FontInfo(DEFAULT_FONT, 1.5f); microBorders.fontInfo = new FontInfo(DEFAULT_FONT, (scale == MicroNameMinScale) ? 0.6f : 0.25f, XFontStyle.Bold); microBorders.smallFontInfo = new FontInfo(DEFAULT_FONT, 0.15f, XFontStyle.Bold); microBorders.largeFontInfo = new FontInfo(DEFAULT_FONT, 0.75f, XFontStyle.Bold); macroNames.fontInfo = new FontInfo(DEFAULT_FONT, 8f / 1.4f, XFontStyle.Bold); macroNames.smallFontInfo = new FontInfo(DEFAULT_FONT, 5f / 1.4f, XFontStyle.Regular); capitals.fillColor = Color.Wheat; capitals.textColor = Color.Red; blueZone.pen.color = Color.Blue; amberZone.pen.color = Color.Gold; redZone.pen.color = Color.Red; macroBorders.pen.color = Color.Red; macroRoutes.pen.color = Color.White; microBorders.pen.color = Color.Gray; Color gridColor = Color.Gray; microRoutes.pen.color = Color.Green; Color foregroundColor = Color.White; backgroundColor = Color.Black; Color lightColor = Color.LightGray; Color darkColor = Color.DarkGray; Color dimColor = Color.DimGray; Color highlightColor = Color.Red; microBorders.textColor = Color.Gold; worldWater.fillColor = Color.DeepSkyBlue; worldNoWater.fillColor = Color.White; worldNoWater.pen.color = Color.Empty; float onePixel = 1f / (float)scale; parsecGrid.pen = new PenInfo(gridColor, onePixel); subsectorGrid.pen = new PenInfo(gridColor, onePixel * 2); sectorGrid.pen = new PenInfo(gridColor, (subsectorGrid.visible ? 4 : 2) * onePixel); microBorders.textStyle.Rotation = 0; microBorders.textStyle.Translation = new PointF(0, 0); microBorders.textStyle.Scale = new SizeF(1.0f, 1.0f); microBorders.textStyle.Uppercase = false; sectorName.textStyle.Rotation = -50; sectorName.textStyle.Translation = new PointF(0, 0); sectorName.textStyle.Scale = new SizeF(0.75f, 1.0f); sectorName.textStyle.Uppercase = false; sectorName.textStyle.Wrap = true; subsectorNames.textStyle = sectorName.textStyle; worlds.textStyle.Rotation = 0; worlds.textStyle.Scale = new SizeF(1.0f, 1.0f); worlds.textStyle.Translation = worlds.position; worlds.textStyle.Uppercase = false; useBackgroundImage = false; useGalaxyImage = false; useWorldImages = false; switch (style) { case Style.Poster: { // This is the default - no changes useGalaxyImage = deepBackgroundOpacity > 0.0f; break; } case Style.Atlas: { deepBackgroundOpacity = 0f; grayscale = true; capitals.fillColor = Color.DarkGray; capitals.textColor = Color.Black; amberZone.pen.color = Color.LightGray; blueZone.pen.color = Color.Gray; // TODO: make dashed redZone.pen.color = Color.Black; macroBorders.pen.color = Color.Black; macroRoutes.pen.color = Color.Gray; microBorders.pen.color = Color.Black; microRoutes.pen.color = Color.Gray; foregroundColor = Color.Black; backgroundColor = Color.White; lightColor = Color.DarkGray; darkColor = Color.DarkGray; dimColor = Color.LightGray; highlightColor = Color.Gray; microBorders.textColor = Color.Gray; worldWater.fillColor = Color.Black; worldNoWater.fillColor = Color.Empty; worldNoWater.fillColor = Color.White; worldNoWater.pen = new PenInfo(Color.Black, onePixel); riftOpacity = Math.Min(riftOpacity, 0.70f); showWorldDetailColors = false; break; } case Style.Print: { deepBackgroundOpacity = 0f; foregroundColor = Color.Black; backgroundColor = Color.White; lightColor = Color.DarkGray; darkColor = Color.DarkGray; dimColor = Color.LightGray; microRoutes.pen.color = Color.Gray; microBorders.textColor = Color.Brown; amberZone.pen.color = Color.Gold; worldNoWater.fillColor = Color.White; worldNoWater.pen = new PenInfo(Color.Black, onePixel); riftOpacity = Math.Min(riftOpacity, 0.70f); break; } case Style.Candy: { useWorldImages = true; pseudoRandomStars.visible = false; useBackgroundImage = deepBackgroundOpacity < 1.0f; useGalaxyImage = deepBackgroundOpacity > 0.0f; microBorderStyle = MicroBorderStyle.Curve; sectorGrid.visible = sectorGrid.visible && (scale >= 4 && scale < 32); subsectorGrid.visible = subsectorGrid.visible && (scale >= 32); parsecGrid.visible = false; subsectorGrid.pen.width = 0.03f * (64.0f / (float)scale); subsectorGrid.pen.DashPattern = new double[] { 10.0, 8.0 }; sectorGrid.pen.width = 0.03f * (64.0f / (float)scale); sectorGrid.pen.DashPattern = new double[] { 10.0, 8.0 }; worlds.textBackgroundStyle = TextBackgroundStyle.Shadow; worldDetails = worldDetails & ~WorldDetails.Starport & ~WorldDetails.Allegiance & ~WorldDetails.Bases & ~WorldDetails.Hex; if (scale < CandyMinWorldNameScale) { worldDetails = worldDetails & ~WorldDetails.KeyNames & ~WorldDetails.AllNames; } if (scale < CandyMinUwpScale) { worldDetails = worldDetails & ~WorldDetails.Uwp; } amberZone.pen.color = Color.Goldenrod; sectorName.textStyle.Rotation = 0; sectorName.textStyle.Translation = new PointF(0, -0.25f); sectorName.textStyle.Scale = new SizeF(0.5f, 0.25f); sectorName.textStyle.Uppercase = true; subsectorNames.textStyle.Rotation = 0; subsectorNames.textStyle.Translation = new PointF(0, -0.25f); subsectorNames.textStyle.Scale = new SizeF(0.3f, 0.15f); // Expand subsectorNames.textStyle.Uppercase = true; microBorders.textStyle.Rotation = 0; microBorders.textStyle.Translation = new PointF(0, 0.25f); microBorders.textStyle.Scale = new SizeF(1.0f, 0.5f); // Expand microBorders.textStyle.Uppercase = true; microBorders.pen.color = Color.FromArgb(128, Color.Red); worlds.textStyle.Rotation = 0; worlds.textStyle.Scale = new SizeF(1f, 0.5f); // Expand worlds.textStyle.Translation = new PointF(0, 0); worlds.textStyle.Uppercase = true; if (scale > CandyMaxWorldRelativeScale) { hexContentScale = CandyMaxWorldRelativeScale / (float)scale; } break; } } sectorName.textColor = scale < 16 ? foregroundColor : scale < 48 ? darkColor : dimColor; subsectorNames.textColor = scale < 16 ? foregroundColor : scale < 48 ? darkColor : dimColor; // Cap pen widths when zooming in float penScale = (scale <= 64) ? 1f : (64f / (float)scale); float borderPenWidth = (scale < MicroBorderMinScale) ? 1 : // When rendering vector borders (scale < ParsecMinScale) ? 1 : // When not rendering "hexes" 0.16f * penScale; // ... but cut in half by clipping float routePenWidth = scale <= 16 ? 0.2f : 0.08f * penScale; microBorders.pen.width = borderPenWidth; macroBorders.pen.width = borderPenWidth; microRoutes.pen.width = routePenWidth; amberZone.pen.width = redZone.pen.width = blueZone.pen.width = 0.05f * penScale; macroRoutes.pen.width = borderPenWidth; macroRoutes.pen.DashStyle = XDashStyle.Dash; if (style == Style.Candy) { subsectorNames.textColor = sectorName.textColor = Color.FromArgb(128, Color.Goldenrod); amberZone.pen.width = redZone.pen.width = blueZone.pen.width = 0.035f; microRoutes.pen.width = scale < CandyMaxRouteRelativeScale ? routePenWidth : routePenWidth / 2; macroBorders.pen.width = scale < CandyMaxBorderRelativeScale ? borderPenWidth : borderPenWidth / 4; microBorders.pen.width = scale < CandyMaxBorderRelativeScale ? borderPenWidth : borderPenWidth / 4; } preferredMimeType = (style == Style.Candy) ? System.Net.Mime.MediaTypeNames.Image.Jpeg : Util.MediaTypeName_Image_Png; pseudoRandomStars.fillColor = foregroundColor; macroNames.textColor = foregroundColor; macroNames.textHighlightColor = highlightColor; macroRoutes.textColor = foregroundColor; macroRoutes.textHighlightColor = highlightColor; worlds.textColor = foregroundColor; worlds.textHighlightColor = highlightColor; hexNumber.textColor = lightColor; imageBorderColor = lightColor; }
private const float WorldUwpMinScale = 96; // Above this: UWP shown above name #endregion Fields #region Constructors public Stylesheet(double scale, MapOptions options, Style style) { grayscale = false; subsectorGrid.visible = ((scale >= SubsectorsMinScale) && options.HasFlag(MapOptions.SubsectorGrid)); sectorGrid.visible = ((scale >= SectorGridMinScale) && options.HasFlag(MapOptions.SectorGrid)); parsecGrid.visible = (scale >= ParsecMinScale); showSomeSectorNames = ((scale >= SectorNameMinScale) && (scale <= SectorNameMaxScale) && ((options & MapOptions.SectorsMask) != 0)); showAllSectorNames = showSomeSectorNames && ((scale >= SectorNameAllSelectedScale) || options.HasFlag(MapOptions.SectorsAll)); subsectorNames.visible = ((scale >= SubsectorNameMinScale) && (scale <= SubsectorNameMaxScale) && ((options & MapOptions.SectorsMask) != 0)); worlds.visible = (scale >= WorldMinScale); pseudoRandomStars.visible = (PseudoRandomStarsMinScale <= scale) && (scale <= PseudoRandomStarsMaxScale); showRifts = (scale <= PseudoRandomStarsMaxScale || style == Style.Candy); float logscale = (float)Math.Log(scale, 2.0); riftOpacity = Util.Clamp((logscale - -2f) / (2f - -2f), 0.0f, 1.0f) * 0.85f; deepBackgroundOpacity = 1.0f - Util.Clamp((logscale - -3f) / (0f - -3f), 0f, 1f); macroRoutes.visible = (scale >= MacroRouteMinScale) && (scale <= MacroRouteMaxScale); macroNames.visible = (scale >= MacroLabelMinScale) && (scale <= MacroLabelMaxScale); showMicroNames = ((scale >= MicroNameMinScale) && ((options & MapOptions.NamesMask) != 0)); capitals.visible = (scale >= MacroWorldsMinScale) && (scale <= MacroWorldsMaxScale); microBorderStyle = (((options & MapOptions.ForceHexes) == 0) && (scale < ParsecHexMinScale)) ? MicroBorderStyle.Square : MicroBorderStyle.Hex; macroBorders.visible = (scale >= MacroBorderMinScale) && (scale < MicroBorderMinScale) && ((options & MapOptions.BordersMask) != 0); microBorders.visible = (scale >= MicroBorderMinScale) && ((options & MapOptions.BordersMask) != 0); fillMicroBorders = microBorders.visible && options.HasFlag(MapOptions.FilledBorders); microRoutes.visible = (scale >= RouteMinScale); worldDetails = !worlds.visible ? 0 : (scale < WorldBasicMinScale) ? WorldDetails.Dotmap : (scale < WorldFullMinScale) ? WorldDetails.Atlas : WorldDetails.Poster; showWorldDetailColors = worldDetails == WorldDetails.Poster && options.HasFlag(MapOptions.WorldColors); lowerCaseAllegiance = (scale < WorldFullMinScale); worlds.textBackgroundStyle = TextBackgroundStyle.Rectangle; hexCoordinateStyle = HexCoordinateStyle.Sector; if (scale < WorldFullMinScale) { // Atlas-style const float x = 0.225f; const float y = 0.125f; BaseTopPosition.X = -x; BaseTopPosition.Y = -y; BaseBottomPosition.X = -x; BaseBottomPosition.Y = y; GasGiantPosition.X = x; GasGiantPosition.Y = -y; AllegiancePosition.X = x; AllegiancePosition.Y = y; BaseMiddlePosition.X = options.HasFlag(MapOptions.ForceHexes) ? -0.35f : -0.2f; BaseMiddlePosition.Y = 0; StarportPosition.X = 0.0f; StarportPosition.Y = -0.24f; worlds.position.X = 0.0f; worlds.position.Y = 0.4f; } else { // Poster-style const float x = 0.25f; const float y = 0.18f; BaseTopPosition.X = -x; BaseTopPosition.Y = -y; BaseBottomPosition.X = -x; BaseBottomPosition.Y = y; GasGiantPosition.X = x; GasGiantPosition.Y = -y; AllegiancePosition.X = x; AllegiancePosition.Y = y; BaseMiddlePosition.X = -0.35f; BaseMiddlePosition.Y = 0f; StarportPosition.X = 0f; StarportPosition.Y = -0.225f; worlds.position.X = 0.0f; worlds.position.Y = 0.37f; // Don't hide hex bottom, leave room for UWP } if (scale >= WorldUwpMinScale) { worldDetails |= WorldDetails.Uwp; BaseBottomPosition.Y = 0.1f; BaseMiddlePosition.Y = (BaseBottomPosition.Y + BaseTopPosition.Y) / 2; AllegiancePosition.Y = 0.1f; } if (worlds.visible) { float fontScale = (scale <= 96f || style == Style.Candy) ? 1f : 96f / (float)scale; worlds.fontInfo = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.2f : 0.15f * fontScale, XFontStyle.Bold); wingdingFont = new FontInfo("Wingdings", scale < WorldFullMinScale ? 0.2f : 0.175f * fontScale); glyphFont = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.175f : 0.15f * fontScale, XFontStyle.Bold); hexNumber.fontInfo = new FontInfo(DEFAULT_FONT, 0.1f * fontScale); worlds.smallFontInfo = new FontInfo(DEFAULT_FONT, scale < WorldFullMinScale ? 0.2f : 0.1f * fontScale, XFontStyle.Regular); starportFont = (scale < WorldFullMinScale) ? worlds.smallFontInfo : worlds.fontInfo; } sectorName.fontInfo = new FontInfo(DEFAULT_FONT, 5.5f); subsectorNames.fontInfo = new FontInfo(DEFAULT_FONT, 1.5f); microBorders.fontInfo = new FontInfo(DEFAULT_FONT, (scale == MicroNameMinScale) ? 0.6f : 0.25f, XFontStyle.Bold); microBorders.smallFontInfo = new FontInfo(DEFAULT_FONT, 0.15f, XFontStyle.Bold); microBorders.largeFontInfo = new FontInfo(DEFAULT_FONT, 0.75f, XFontStyle.Bold); macroNames.fontInfo = new FontInfo(DEFAULT_FONT, 8f / 1.4f, XFontStyle.Bold); macroNames.smallFontInfo = new FontInfo(DEFAULT_FONT, 5f / 1.4f, XFontStyle.Regular); capitals.fillColor = Color.Wheat; capitals.textColor = Color.Red; blueZone.pen.color = Color.Blue; amberZone.pen.color = Color.Gold; redZone.pen.color = Color.Red; macroBorders.pen.color = Color.Red; macroRoutes.pen.color = Color.White; microBorders.pen.color = Color.Gray; Color gridColor = Color.Gray; microRoutes.pen.color = Color.Green; Color foregroundColor = Color.White; backgroundColor = Color.Black; Color lightColor = Color.LightGray; Color darkColor = Color.DarkGray; Color dimColor = Color.DimGray; Color highlightColor = Color.Red; microBorders.textColor = Color.Gold; worldWater.fillColor = Color.DeepSkyBlue; worldNoWater.fillColor = Color.White; worldNoWater.pen.color = Color.Empty; float onePixel = 1f / (float)scale; parsecGrid.pen = new PenInfo(gridColor, onePixel); subsectorGrid.pen = new PenInfo(gridColor, onePixel * 2); sectorGrid.pen = new PenInfo(gridColor, (subsectorGrid.visible ? 4 : 2) * onePixel); microBorders.textStyle.Rotation = 0; microBorders.textStyle.Translation = new PointF(0, 0); microBorders.textStyle.Scale = new SizeF(1.0f, 1.0f); microBorders.textStyle.Uppercase = false; sectorName.textStyle.Rotation = -50; sectorName.textStyle.Translation = new PointF(0, 0); sectorName.textStyle.Scale = new SizeF(0.75f, 1.0f); sectorName.textStyle.Uppercase = false; sectorName.textStyle.Wrap = true; subsectorNames.textStyle = sectorName.textStyle; worlds.textStyle.Rotation = 0; worlds.textStyle.Scale = new SizeF(1.0f, 1.0f); worlds.textStyle.Translation = worlds.position; worlds.textStyle.Uppercase = false; useBackgroundImage = false; useGalaxyImage = false; useWorldImages = false; switch (style) { case Style.Poster: { // This is the default - no changes useGalaxyImage = deepBackgroundOpacity > 0.0f; break; } case Style.Atlas: { deepBackgroundOpacity = 0f; grayscale = true; capitals.fillColor = Color.DarkGray; capitals.textColor = Color.Black; amberZone.pen.color = Color.LightGray; blueZone.pen.color = Color.Gray; // TODO: make dashed redZone.pen.color = Color.Black; macroBorders.pen.color = Color.Black; macroRoutes.pen.color = Color.Gray; microBorders.pen.color = Color.Black; microRoutes.pen.color = Color.Gray; foregroundColor = Color.Black; backgroundColor = Color.White; lightColor = Color.DarkGray; darkColor = Color.DarkGray; dimColor = Color.LightGray; highlightColor = Color.Gray; microBorders.textColor = Color.Gray; worldWater.fillColor = Color.Black; worldNoWater.fillColor = Color.Empty; worldNoWater.fillColor = Color.White; worldNoWater.pen = new PenInfo(Color.Black, onePixel); riftOpacity = Math.Min(riftOpacity, 0.70f); showWorldDetailColors = false; break; } case Style.Print: { deepBackgroundOpacity = 0f; foregroundColor = Color.Black; backgroundColor = Color.White; lightColor = Color.DarkGray; darkColor = Color.DarkGray; dimColor = Color.LightGray; microRoutes.pen.color = Color.Gray; microBorders.textColor = Color.Brown; amberZone.pen.color = Color.Gold; worldNoWater.fillColor = Color.White; worldNoWater.pen = new PenInfo(Color.Black, onePixel); riftOpacity = Math.Min(riftOpacity, 0.70f); break; } case Style.Candy: { useWorldImages = true; pseudoRandomStars.visible = false; useBackgroundImage = deepBackgroundOpacity < 1.0f; useGalaxyImage = deepBackgroundOpacity > 0.0f; microBorderStyle = MicroBorderStyle.Curve; sectorGrid.visible = sectorGrid.visible && (scale >= 4 && scale < 32); subsectorGrid.visible = subsectorGrid.visible && (scale >= 32); parsecGrid.visible = false; subsectorGrid.pen.width = 0.03f * (64.0f / (float)scale); subsectorGrid.pen.DashPattern = new double[] { 10.0, 8.0 }; sectorGrid.pen.width = 0.03f * (64.0f / (float)scale); sectorGrid.pen.DashPattern = new double[] { 10.0, 8.0 }; worlds.textBackgroundStyle = TextBackgroundStyle.Shadow; worldDetails = worldDetails & ~WorldDetails.Starport & ~WorldDetails.Allegiance & ~WorldDetails.Bases & ~WorldDetails.Hex; if (scale < CandyMinWorldNameScale) worldDetails = worldDetails & ~WorldDetails.KeyNames & ~WorldDetails.AllNames; if (scale < CandyMinUwpScale) worldDetails = worldDetails & ~WorldDetails.Uwp; amberZone.pen.color = Color.Goldenrod; sectorName.textStyle.Rotation = 0; sectorName.textStyle.Translation = new PointF(0, -0.25f); sectorName.textStyle.Scale = new SizeF(0.5f, 0.25f); sectorName.textStyle.Uppercase = true; subsectorNames.textStyle.Rotation = 0; subsectorNames.textStyle.Translation = new PointF(0, -0.25f); subsectorNames.textStyle.Scale = new SizeF(0.3f, 0.15f); // Expand subsectorNames.textStyle.Uppercase = true; microBorders.textStyle.Rotation = 0; microBorders.textStyle.Translation = new PointF(0, 0.25f); microBorders.textStyle.Scale = new SizeF(1.0f, 0.5f); // Expand microBorders.textStyle.Uppercase = true; microBorders.pen.color = Color.FromArgb(128, Color.Red); worlds.textStyle.Rotation = 0; worlds.textStyle.Scale = new SizeF(1f, 0.5f); // Expand worlds.textStyle.Translation = new PointF(0, 0); worlds.textStyle.Uppercase = true; if (scale > CandyMaxWorldRelativeScale) { hexContentScale = CandyMaxWorldRelativeScale / (float)scale; } break; } } sectorName.textColor = scale < 16 ? foregroundColor : scale < 48 ? darkColor : dimColor; subsectorNames.textColor = scale < 16 ? foregroundColor : scale < 48 ? darkColor : dimColor; // Cap pen widths when zooming in float penScale = (scale <= 64) ? 1f : (64f / (float)scale); float borderPenWidth = (scale < MicroBorderMinScale) ? 1 : // When rendering vector borders (scale < ParsecMinScale) ? 1 : // When not rendering "hexes" 0.16f * penScale; // ... but cut in half by clipping float routePenWidth = scale <= 16 ? 0.2f : 0.08f * penScale; microBorders.pen.width = borderPenWidth; macroBorders.pen.width = borderPenWidth; microRoutes.pen.width = routePenWidth; amberZone.pen.width = redZone.pen.width = blueZone.pen.width = 0.05f * penScale; macroRoutes.pen.width = borderPenWidth; macroRoutes.pen.DashStyle = XDashStyle.Dash; if (style == Style.Candy) { subsectorNames.textColor = sectorName.textColor = Color.FromArgb(128, Color.Goldenrod); amberZone.pen.width = redZone.pen.width = blueZone.pen.width = 0.035f; microRoutes.pen.width = scale < CandyMaxRouteRelativeScale ? routePenWidth : routePenWidth / 2; macroBorders.pen.width = scale < CandyMaxBorderRelativeScale ? borderPenWidth : borderPenWidth / 4; microBorders.pen.width = scale < CandyMaxBorderRelativeScale ? borderPenWidth : borderPenWidth / 4; } preferredMimeType = (style == Style.Candy) ? System.Net.Mime.MediaTypeNames.Image.Jpeg : Util.MediaTypeName_Image_Png; pseudoRandomStars.fillColor = foregroundColor; macroNames.textColor = foregroundColor; macroNames.textHighlightColor = highlightColor; macroRoutes.textColor = foregroundColor; macroRoutes.textHighlightColor = highlightColor; worlds.textColor = foregroundColor; worlds.textHighlightColor = highlightColor; hexNumber.textColor = lightColor; imageBorderColor = lightColor; }