private static void RenderToGraphics(Render.RenderContext ctx, int rot, float translateX, float translateY, XGraphics graphics) { graphics.TranslateTransform(translateX, translateY); graphics.RotateTransform(rot * 90); using (Maps.Rendering.RenderUtil.SaveState(graphics)) { if (ctx.clipPath != null) { XMatrix m = ctx.ImageSpaceToWorldSpace; graphics.MultiplyTransform(m); graphics.IntersectClip(ctx.clipPath); m.Invert(); graphics.MultiplyTransform(m); } ctx.graphics = graphics; Maps.Rendering.Render.RenderTile(ctx); } if (ctx.border && ctx.clipPath != null) { using (Maps.Rendering.RenderUtil.SaveState(graphics)) { // Render border in world space XMatrix m = ctx.ImageSpaceToWorldSpace; graphics.MultiplyTransform(m); XPen pen = new XPen(ctx.styles.imageBorderColor, 0.2f); // PdfSharp can't ExcludeClip so we take advantage of the fact that we know // the path starts on the left edge and proceeds clockwise. We extend the // path with a counterclockwise border around it, then use that to exclude // the original path's region for rendering the border. ctx.clipPath.Flatten(); RectangleF bounds = PathUtil.Bounds(ctx.clipPath); bounds.Inflate(2 * (float)pen.Width, 2 * (float)pen.Width); List<byte> types = new List<byte>(ctx.clipPath.Internals.GdiPath.PathTypes); List<PointF> points = new List<PointF>(ctx.clipPath.Internals.GdiPath.PathPoints); PointF key = points[0]; points.Add(new PointF(bounds.Left, key.Y)); types.Add(1); points.Add(new PointF(bounds.Left, bounds.Bottom)); types.Add(1); points.Add(new PointF(bounds.Right, bounds.Bottom)); types.Add(1); points.Add(new PointF(bounds.Right, bounds.Top)); types.Add(1); points.Add(new PointF(bounds.Left, bounds.Top)); types.Add(1); points.Add(new PointF(bounds.Left, key.Y)); types.Add(1); points.Add(new PointF(key.X, key.Y)); types.Add(1); XGraphicsPath path = new XGraphicsPath(points.ToArray(), types.ToArray(), XFillMode.Winding); graphics.IntersectClip(path); graphics.DrawPath(pen, ctx.clipPath); } } }
public void Fill(XGraphics graphics, RectangleF rect, Brush fillBrush) { if (graphics == null) throw new ArgumentNullException("graphics"); RectangleF bounds = TransformedBounds; if (bounds.IntersectsWith(rect)) { XGraphicsPath path = Path; using (RenderUtil.SaveState(graphics)) { XMatrix matrix = new XMatrix(); matrix.ScalePrepend(ScaleX, ScaleY); matrix.TranslatePrepend(-OriginX, -OriginY); graphics.MultiplyTransform(matrix); graphics.DrawPath(fillBrush, path); } } }
public override void RenderPage(XGraphics gfx) { base.RenderPage(gfx); PointF[] origins = new PointF[] { new PointF(100, 200), new PointF(300, 200), new PointF(100, 400), new PointF(300, 400), new PointF(100, 600), new PointF(350, 600), }; PointF origin; XGraphicsContainer container; float length = 100; // Not transformed origin = origins[0]; DrawAxes(gfx, XPens.Black, origin, length); gfx.DrawString(this.properties.Font2.Text, this.properties.Font2.Font, this.properties.Font2.Brush, origin); // Translation container = gfx.BeginContainer(new RectangleF(10, 10, 1, 1), new RectangleF(0, 0, 1, 1), XGraphicsUnit.Point); origin = origins[1]; DrawAxes(gfx, XPens.Black, origin, length); gfx.TranslateTransform(20, -30); DrawAxes(gfx, XPens.DarkGray, origin, length); gfx.DrawString(this.properties.Font2.Text, this.properties.Font2.Font, this.properties.Font2.Brush, origin); gfx.EndContainer(container); // Scaling container = gfx.BeginContainer(new RectangleF(0, 0, 1, 1), new RectangleF(0, 0, 1, 1), XGraphicsUnit.Point); origin = origins[2]; DrawAxes(gfx, XPens.Black, origin, length); gfx.TranslateTransform(origin.X, origin.Y); gfx.ScaleTransform(1.3f, 1.5f); DrawAxes(gfx, XPens.DarkGray, new PointF(), length); gfx.DrawString(this.properties.Font2.Text, this.properties.Font2.Font, this.properties.Font2.Brush, 0, 0); gfx.EndContainer(container); // Rotation container = gfx.BeginContainer(new RectangleF(0, 0, 1, 1), new RectangleF(0, 0, 1, 1), XGraphicsUnit.Point); origin = origins[3]; DrawAxes(gfx, XPens.Black, origin, length); gfx.TranslateTransform(origin.X, origin.Y); gfx.RotateTransform(-45); DrawAxes(gfx, XPens.DarkGray, new PointF(), length); gfx.DrawString(this.properties.Font2.Text, this.properties.Font2.Font, this.properties.Font2.Brush, 0 , 0); gfx.EndContainer(container); // Skewing (or shearing) container = gfx.BeginContainer(new RectangleF(0, 0, 1, 1), new RectangleF(0, 0, 1, 1), XGraphicsUnit.Point); origin = origins[4]; DrawAxes(gfx, XPens.Black, origin, length); gfx.TranslateTransform(origin.X, origin.Y); gfx.MultiplyTransform(new Matrix(1, -0.3f, -0.4f, 1, 0, 0)); DrawAxes(gfx, XPens.DarkGray, new PointF(), length); gfx.DrawString(this.properties.Font2.Text, this.properties.Font2.Font, this.properties.Font2.Brush, 0 , 0); gfx.EndContainer(container); // Reflection container = gfx.BeginContainer(new RectangleF(0, 0, 1, 1), new RectangleF(0, 0, 1, 1), XGraphicsUnit.Point); origin = origins[5]; DrawAxes(gfx, XPens.Black, origin, length); gfx.TranslateTransform(origin.X, origin.Y); gfx.MultiplyTransform(new Matrix(-1, 0, 0, -1, 0, 0)); DrawAxes(gfx, XPens.DarkGray, new PointF(), length); gfx.DrawString(this.properties.Font2.Text, this.properties.Font2.Font, this.properties.Font2.Brush, 0 , 0); gfx.EndContainer(container); }
public void DrawName(XGraphics graphics, RectangleF rect, MapOptions options, XFont font, XBrush textBrush, LabelStyle labelStyle) { if (graphics == null) throw new ArgumentNullException("graphics"); RectangleF bounds = TransformedBounds; if (bounds.IntersectsWith(rect)) { if (Name != null) { string str = Name; if (labelStyle.Uppercase) str = str.ToUpperInvariant(); PointF pos = NamePosition;// PointF( bounds.Left + bounds.Width / 2, bounds.Top + bounds.Height / 2 ); using (RenderUtil.SaveState(graphics)) { XMatrix matrix = new XMatrix(); matrix.TranslatePrepend(pos.X, pos.Y); matrix.ScalePrepend(1.0f / Astrometrics.ParsecScaleX, 1.0f / Astrometrics.ParsecScaleY); matrix.RotatePrepend(-labelStyle.Rotation); // Rotate it graphics.MultiplyTransform(matrix, XMatrixOrder.Prepend); XSize size = graphics.MeasureString(str, font); graphics.TranslateTransform(-size.Width / 2, -size.Height / 2); // Center the text RectangleF textBounds = new RectangleF(0, 0, (float)size.Width, (float)size.Height * 2); // *2 or it gets cut off at high sizes XTextFormatter tf = new XTextFormatter(graphics); tf.Alignment = XParagraphAlignment.Center; tf.DrawString(str, font, textBrush, textBounds); } } } }
public void Draw(XGraphics graphics, RectangleF rect, MapOptions options, XPen pen) { if (graphics == null) throw new ArgumentNullException("graphics"); RectangleF bounds = TransformedBounds; //graphics.DrawRectangle( new XPen(XColors.Yellow, 1), bounds.X, bounds.Y, bounds.Width, bounds.Height ); if (bounds.IntersectsWith(rect)) { XGraphicsPath path = Path; using (RenderUtil.SaveState(graphics)) { XMatrix matrix = new XMatrix(); matrix.ScalePrepend(ScaleX, ScaleY); matrix.TranslatePrepend(-OriginX, -OriginY); graphics.MultiplyTransform(matrix, XMatrixOrder.Prepend); graphics.DrawPath(pen, path); } } }
public override void RenderPage(XGraphics gfx) { //base.RenderPage(gfx); XPoint[] origins = new XPoint[] { new XPoint(100, 200), new XPoint(300, 200), new XPoint(100, 400), new XPoint(300, 400), new XPoint(100, 600), new XPoint(350, 600), }; XPoint origin; XGraphicsState state; float length = 100; // Not transformed origin = origins[0]; DrawAxes(gfx, XPens.Black, origin, length); gfx.DrawString(this.properties.Font1.Text, this.properties.Font1.Font, this.properties.Font1.Brush, origin); // Translation state = gfx.Save(); origin = origins[1]; DrawAxes(gfx, XPens.Black, origin, length); gfx.TranslateTransform(20, -30); DrawAxes(gfx, XPens.DarkGray, origin, length); gfx.DrawString(this.properties.Font1.Text, this.properties.Font1.Font, this.properties.Font1.Brush, origin); gfx.Restore(state); // Translation state = gfx.Save(); origin = origins[2]; DrawAxes(gfx, XPens.Black, origin, length); gfx.TranslateTransform(20, -30); DrawAxes(gfx, XPens.DarkGray, origin, length); gfx.DrawString(this.properties.Font1.Text, this.properties.Font1.Font, this.properties.Font1.Brush, origin); gfx.Restore(state); //// Scaling //state = gfx.Save(); //origin = origins[2]; //DrawAxes(gfx, XPens.Black, origin, length); //gfx.TranslateTransform(origin.X, origin.Y); //gfx.ScaleTransform(1.3, 1.5); //DrawAxes(gfx, XPens.DarkGray, new XPoint(), length); //gfx.DrawString(this.properties.Font1.Text, this.properties.Font1.Font, this.properties.Font1.Brush, 0, 0); //gfx.Restore(state); // Rotation state = gfx.Save(); origin = origins[3]; DrawAxes(gfx, XPens.Black, origin, length); gfx.TranslateTransform(origin.X, origin.Y); gfx.RotateTransform(-45); DrawAxes(gfx, XPens.DarkGray, new XPoint(), length); gfx.DrawString(this.properties.Font1.Text, this.properties.Font1.Font, this.properties.Font1.Brush, 0 , 0); gfx.Restore(state); // Skewing (or shearing) state = gfx.Save(); origin = origins[4]; DrawAxes(gfx, XPens.Black, origin, length); gfx.TranslateTransform(origin.X, origin.Y); gfx.MultiplyTransform(new Matrix(1, -0.3f, -0.4f, 1, 0, 0)); DrawAxes(gfx, XPens.DarkGray, new XPoint(), length); gfx.DrawString(this.properties.Font1.Text, this.properties.Font1.Font, this.properties.Font1.Brush, 0 , 0); gfx.Restore(state); // Reflection state = gfx.Save(); origin = origins[5]; DrawAxes(gfx, XPens.Black, origin, length); gfx.TranslateTransform(origin.X, origin.Y); gfx.MultiplyTransform(new Matrix(-1, 0, 0, -1, 0, 0)); DrawAxes(gfx, XPens.DarkGray, new XPoint(), length); gfx.DrawString(this.properties.Font1.Text, this.properties.Font1.Font, this.properties.Font1.Brush, 0 , 0); gfx.Restore(state); }
public void Render(XGraphics graphics) { this.graphics = graphics; solidBrush = new XSolidBrush(); pen = new XPen(XColor.Empty); List<Timer> timers = new List<Timer>(); using (var fonts = new FontCache(styles)) { #region resources lock (s_imageInitLock) { if (styles.showNebulaBackground && s_nebulaImage == null) s_nebulaImage = XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Nebula.png")); if (styles.showRiftOverlay && s_riftImage == null) s_riftImage = new ImageHolder(Image.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Rifts.png"))); if (styles.showGalaxyBackground && s_galaxyImage == null) { // TODO: Don't load both unless necessary s_galaxyImage = new ImageHolder(Image.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Galaxy.png"))); s_galaxyImageGray = new ImageHolder(Image.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Galaxy_Gray.png"))); } if (styles.useWorldImages && s_worldImages == null) { s_worldImages = new Dictionary<string, XImage> { { "Hyd0", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Hyd0.png")) }, { "Hyd1", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Hyd1.png")) }, { "Hyd2", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Hyd2.png")) }, { "Hyd3", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Hyd3.png")) }, { "Hyd4", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Hyd4.png")) }, { "Hyd5", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Hyd5.png")) }, { "Hyd6", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Hyd6.png")) }, { "Hyd7", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Hyd7.png")) }, { "Hyd8", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Hyd8.png")) }, { "Hyd9", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Hyd9.png")) }, { "HydA", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/HydA.png")) }, { "Belt", XImage.FromFile(resourceManager.Server.MapPath(@"~/res/Candy/Belt.png")) } }; } if (Silly && s_sillyImageColor == null) { // Happy face c/o http://bighappyfaces.com/ s_sillyImageColor = XImage.FromFile(resourceManager.Server.MapPath(@"~/res/AprilFools/Starburst.png")); s_sillyImageGray = XImage.FromFile(resourceManager.Server.MapPath(@"~/res/AprilFools/Starburst_Gray.png")); } } #endregion timers.Add(new Timer("preload")); ////////////////////////////////////////////////////////////// // // Image-Space Rendering // ////////////////////////////////////////////////////////////// using (RenderUtil.SaveState(graphics)) { if (ClipPath != null) { graphics.MultiplyTransform(imageSpaceToWorldSpace); graphics.IntersectClip(ClipPath); graphics.MultiplyTransform(worldSpaceToImageSpace); } // Fill graphics.SmoothingMode = XSmoothingMode.HighSpeed; solidBrush.Color = styles.backgroundColor; graphics.DrawRectangle(solidBrush, 0, 0, tileSize.Width, tileSize.Height); } timers.Add(new Timer("imagespace")); ////////////////////////////////////////////////////////////// // // World-Space Rendering // ////////////////////////////////////////////////////////////// graphics.MultiplyTransform(imageSpaceToWorldSpace); using (RenderUtil.SaveState(graphics)) { //------------------------------------------------------------ // Explicit Clipping //------------------------------------------------------------ if (ClipPath != null) graphics.IntersectClip(ClipPath); //------------------------------------------------------------ // Background //------------------------------------------------------------ timers.Add(new Timer("prep")); #region nebula-background //------------------------------------------------------------ // Local background (Nebula) //------------------------------------------------------------ // NOTE: Since alpha texture brushes aren't supported without // creating a new image (slow!) we render the local background // first, then overlay the deep background over it, for // basically the same effect since the alphas sum to 1. if (styles.showNebulaBackground) DrawNebulaBackground(); timers.Add(new Timer("background (nebula)")); #endregion #region galaxy-background //------------------------------------------------------------ // Deep background (Galaxy) //------------------------------------------------------------ if (styles.showGalaxyBackground && styles.deepBackgroundOpacity > 0f && galacticBounds.IntersectsWith(tileRect)) { using (RenderUtil.SaveState(graphics)) { graphics.MultiplyTransform(xformLinehanToMikesh); ImageHolder galaxyImage = styles.lightBackground ? s_galaxyImageGray : s_galaxyImage; RenderUtil.DrawImageAlpha(graphics, styles.deepBackgroundOpacity, galaxyImage, galaxyImageRect); } } timers.Add(new Timer("background (galaxy)")); #endregion #region pseudorandom-stars //------------------------------------------------------------ // Pseudo-Random Stars //------------------------------------------------------------ if (styles.pseudoRandomStars.visible) DrawPseudoRandomStars(); timers.Add(new Timer("pseudorandom")); #endregion #region rifts //------------------------------------------------------------ // Rifts in Charted Space //------------------------------------------------------------ if (styles.showRiftOverlay && styles.riftOpacity > 0f) RenderUtil.DrawImageAlpha(graphics, styles.riftOpacity, s_riftImage, riftImageRect); timers.Add(new Timer("rifts")); #endregion #region april-fools //------------------------------------------------------------ // April Fool's Day //------------------------------------------------------------ if (Silly) { using (RenderUtil.SaveState(graphics)) { // Render in image-space graphics.MultiplyTransform(worldSpaceToImageSpace); XImage sillyImage = styles.grayscale ? s_sillyImageGray : s_sillyImageColor; lock (sillyImage) { graphics.DrawImage(sillyImage, 0, 0, tileSize.Width, tileSize.Height); } } timers.Add(new Timer("silly")); } #endregion //------------------------------------------------------------ // Foreground //------------------------------------------------------------ #region macro-borders //------------------------------------------------------------ // Macro: Borders object //------------------------------------------------------------ if (styles.macroBorders.visible) { styles.macroBorders.pen.Apply(ref pen); graphics.SmoothingMode = XSmoothingMode.AntiAlias; foreach (var vec in borderFiles .Select(file => resourceManager.GetXmlFileObject(file, typeof(VectorObject))) .OfType<VectorObject>() .Where(vec => (vec.MapOptions & options & MapOptions.BordersMask) != 0)) { vec.Draw(graphics, tileRect, pen); } } timers.Add(new Timer("macro-borders")); #endregion #region macro-routes //------------------------------------------------------------ // Macro: Route object //------------------------------------------------------------ if (styles.macroRoutes.visible) { styles.macroRoutes.pen.Apply(ref pen); graphics.SmoothingMode = XSmoothingMode.AntiAlias; foreach (var vec in routeFiles .Select(file => resourceManager.GetXmlFileObject(file, typeof(VectorObject))) .OfType<VectorObject>() .Where(vec => (vec.MapOptions & options & MapOptions.BordersMask) != 0)) { vec.Draw(graphics, tileRect, pen); } } timers.Add(new Timer("macro-routes")); #endregion #region sector-grid //------------------------------------------------------------ // Sector Grid //------------------------------------------------------------ graphics.SmoothingMode = XSmoothingMode.HighSpeed; if (styles.sectorGrid.visible) { const int gridSlop = 10; styles.sectorGrid.pen.Apply(ref pen); for (float h = ((float)(Math.Floor((tileRect.Left) / Astrometrics.SectorWidth) - 1) - Astrometrics.ReferenceSector.X) * Astrometrics.SectorWidth - Astrometrics.ReferenceHex.X; h <= tileRect.Right + Astrometrics.SectorWidth; h += Astrometrics.SectorWidth) graphics.DrawLine(pen, h, tileRect.Top - gridSlop, h, tileRect.Bottom + gridSlop); for (float v = ((float)(Math.Floor((tileRect.Top) / Astrometrics.SectorHeight) - 1) - Astrometrics.ReferenceSector.Y) * Astrometrics.SectorHeight - Astrometrics.ReferenceHex.Y; v <= tileRect.Bottom + Astrometrics.SectorHeight; v += Astrometrics.SectorHeight) graphics.DrawLine(pen, tileRect.Left - gridSlop, v, tileRect.Right + gridSlop, v); } timers.Add(new Timer("sector grid")); #endregion #region subsector-grid //------------------------------------------------------------ // Subsector Grid //------------------------------------------------------------ graphics.SmoothingMode = XSmoothingMode.HighSpeed; if (styles.subsectorGrid.visible) { const int gridSlop = 10; styles.subsectorGrid.pen.Apply(ref pen); int hmin = (int)Math.Floor(tileRect.Left / Astrometrics.SubsectorWidth) - 1 - Astrometrics.ReferenceSector.X, hmax = (int)Math.Ceiling((tileRect.Right + Astrometrics.SubsectorWidth + Astrometrics.ReferenceHex.X) / Astrometrics.SubsectorWidth); for (int hi = hmin; hi <= hmax; ++hi) { if (hi % 4 == 0) continue; float h = hi * Astrometrics.SubsectorWidth - Astrometrics.ReferenceHex.X; graphics.DrawLine(pen, h, tileRect.Top - gridSlop, h, tileRect.Bottom + gridSlop); } int vmin = (int)Math.Floor(tileRect.Top / Astrometrics.SubsectorHeight) - 1 - Astrometrics.ReferenceSector.Y, vmax = (int)Math.Ceiling((tileRect.Bottom + Astrometrics.SubsectorHeight + Astrometrics.ReferenceHex.Y) / Astrometrics.SubsectorHeight); for (int vi = vmin; vi <= vmax; ++vi) { if (vi % 4 == 0) continue; float v = vi * Astrometrics.SubsectorHeight - Astrometrics.ReferenceHex.Y; graphics.DrawLine(pen, tileRect.Left - gridSlop, v, tileRect.Right + gridSlop, v); } } timers.Add(new Timer("subsector grid")); #endregion #region parsec-grid //------------------------------------------------------------ // Parsec Grid //------------------------------------------------------------ // TODO: Optimize - timers indicate this is slow graphics.SmoothingMode = XSmoothingMode.HighQuality; if (styles.parsecGrid.visible) DrawParsecGrid(); timers.Add(new Timer("parsec grid")); #endregion #region subsector-names //------------------------------------------------------------ // Subsector Names //------------------------------------------------------------ if (styles.subsectorNames.visible) { solidBrush.Color = styles.subsectorNames.textColor; foreach (Sector sector in selector.Sectors) { for (int i = 0; i < 16; i++) { Subsector ss = sector.Subsector(i); if (ss == null || string.IsNullOrEmpty(ss.Name)) continue; Point center = sector.SubsectorCenter(i); RenderUtil.DrawLabel(graphics, ss.Name, center, styles.subsectorNames.Font, solidBrush, styles.subsectorNames.textStyle); } } } timers.Add(new Timer("subsector names")); #endregion #region micro-borders //------------------------------------------------------------ // Micro: Borders //------------------------------------------------------------ if (styles.microBorders.visible) { if (styles.fillMicroBorders) DrawMicroBorders(BorderLayer.Fill); DrawMicroBorders(BorderLayer.Stroke); } timers.Add(new Timer("micro-borders")); #endregion #region micro-routes //------------------------------------------------------------ // Micro: Routes //------------------------------------------------------------ if (styles.microRoutes.visible) DrawRoutes(); timers.Add(new Timer("micro-routes")); #endregion #region micro-border-labels //------------------------------------------------------------ // Micro: Border Labels & Explicit Labels //------------------------------------------------------------ if (styles.showMicroNames) DrawLabels(); timers.Add(new Timer("micro-border labels")); #endregion #region sector-names //------------------------------------------------------------ // Sector Names //------------------------------------------------------------ if (styles.showSomeSectorNames || styles.showAllSectorNames) { foreach (Sector sector in selector.Sectors .Where(sector => styles.showAllSectorNames || (styles.showSomeSectorNames && sector.Selected)) .Where(sector => sector.Names.Any() || sector.Label != null)) { solidBrush.Color = styles.sectorName.textColor; string name = sector.Label ?? sector.Names[0].Text; RenderUtil.DrawLabel(graphics, name, sector.Center, styles.sectorName.Font, solidBrush, styles.sectorName.textStyle); } } timers.Add(new Timer("sector names")); #endregion #region government-rift-names //------------------------------------------------------------ // Macro: Government / Rift / Route Names //------------------------------------------------------------ if (styles.macroNames.visible) DrawMacroNames(); timers.Add(new Timer("macro names")); #endregion #region capitals-homeworlds //------------------------------------------------------------ // Macro: Capitals & Home Worlds //------------------------------------------------------------ if (styles.capitals.visible && (options & MapOptions.WorldsMask) != 0) { WorldObjectCollection worlds = resourceManager.GetXmlFileObject(@"~/res/Worlds.xml", typeof(WorldObjectCollection)) as WorldObjectCollection; if (worlds != null && worlds.Worlds != null) { solidBrush.Color = styles.capitals.textColor; foreach (WorldObject world in worlds.Worlds.Where(world => (world.MapOptions & options) != 0)) { world.Paint(graphics, styles.capitals.fillColor, solidBrush, styles.macroNames.SmallFont); } } } timers.Add(new Timer("macro worlds")); #endregion #region mega-names //------------------------------------------------------------ // Mega: Galaxy-Scale Labels //------------------------------------------------------------ if (styles.megaNames.visible) { solidBrush.Color = styles.megaNames.textColor; foreach (var label in megaLabels) { using (RenderUtil.SaveState(graphics)) { XMatrix matrix = new XMatrix(); matrix.ScalePrepend(1.0f / Astrometrics.ParsecScaleX, 1.0f / Astrometrics.ParsecScaleY); matrix.TranslatePrepend(label.position.X, label.position.Y); graphics.MultiplyTransform(matrix, XMatrixOrder.Prepend); XFont font = label.minor ? styles.megaNames.SmallFont : styles.megaNames.Font; XSize size = graphics.MeasureString(label.text, font); graphics.TranslateTransform(-size.Width / 2, -size.Height / 2); // Center the text RectangleF textBounds = new RectangleF(0, 0, (float)size.Width * 1.01f, (float)size.Height * 2); // *2 or it gets cut off at high sizes XTextFormatter formatter = new XTextFormatter(graphics); formatter.Alignment = XParagraphAlignment.Center; formatter.DrawString(label.text, font, solidBrush, textBounds); } } } timers.Add(new Timer("mega names")); #endregion } // End of clipping, so world names are not clipped in jumpmaps. #region worlds //------------------------------------------------------------ // Worlds //------------------------------------------------------------ if (styles.worlds.visible) { // TODO: selector may be expensive foreach (World world in selector.Worlds) { DrawWorld(fonts, world, WorldLayer.Background); } foreach (World world in selector.Worlds) { DrawWorld(fonts, world, WorldLayer.Foreground); } } timers.Add(new Timer("worlds")); #endregion //------------------------------------------------------------ // Overlays //------------------------------------------------------------ #region droyne //------------------------------------------------------------ // Droyne/Chirper Worlds //------------------------------------------------------------ if (styles.droyneWorlds.visible) { solidBrush.Color = styles.droyneWorlds.textColor; foreach (World world in selector.Worlds) { bool droyne = world.HasCodePrefix("Droy") != null; bool chirpers = world.HasCodePrefix("Chir") != null; if (droyne || chirpers) { string glyph = droyne ? "\u2605" : "\u2606"; PointF center = Astrometrics.HexToCenter(world.Coordinates); using (RenderUtil.SaveState(graphics)) { XMatrix matrix = new XMatrix(); matrix.TranslatePrepend(center.X, center.Y); matrix.ScalePrepend(1 / Astrometrics.ParsecScaleX, 1 / Astrometrics.ParsecScaleY); graphics.MultiplyTransform(matrix, XMatrixOrder.Prepend); graphics.DrawString(glyph, styles.droyneWorlds.Font, solidBrush, 0, 0, RenderUtil.StringFormatCentered); } } } } timers.Add(new Timer("droyne")); #endregion #region unofficial //------------------------------------------------------------ // Unofficial //------------------------------------------------------------ if (styles.dimUnofficialSectors && styles.worlds.visible) { solidBrush.Color = Color.FromArgb(128, styles.backgroundColor); foreach (Sector sector in selector.Sectors .Where(sector => !sector.Tags.Contains("Official") && !sector.Tags.Contains("Preserve") && !sector.Tags.Contains("InReview"))) graphics.DrawRectangle(solidBrush, sector.Bounds); } timers.Add(new Timer("unofficial")); #endregion #region timing #if SHOW_TIMING using( RenderUtil.SaveState( graphics ) ) { XFont font = new XFont( FontFamily.GenericSansSerif, 12, XFontStyle.Regular, new XPdfFontOptions(PdfSharp.Pdf.PdfFontEncoding.Unicode) ); graphics.MultiplyTransform( worldSpaceToImageSpace ); double cursorX = 20.0, cursorY = 20.0; DateTime last = dtStart; foreach( Timer s in timers ) { TimeSpan ts = s.dt - last; last = s.dt; for( int dx = -1; dx <= 1; ++dx ) { for( int dy = -1; dy <= 1; ++dy ) { graphics.DrawString( String.Format( "{0} {1}", Math.Round( ts.TotalMilliseconds ), s.label ), font, XBrushes.Black, cursorX + dx, cursorY + dy ); } } graphics.DrawString( String.Format("{0} {1}", Math.Round(ts.TotalMilliseconds), s.label), font, XBrushes.Yellow, cursorX, cursorY ); cursorY += 14; } } #endif #endregion } }
public static void DrawLabel(XGraphics g, string text, PointF labelPos, XFont font, XBrush brush, LabelStyle labelStyle) { using (RenderUtil.SaveState(g)) { XTextFormatter tf = new XTextFormatter(g); tf.Alignment = XParagraphAlignment.Center; XMatrix matrix = new XMatrix(); matrix.TranslatePrepend(labelPos.X, labelPos.Y); matrix.ScalePrepend(1.0f / Astrometrics.ParsecScaleX, 1.0f / Astrometrics.ParsecScaleY); if (labelStyle.Uppercase) text = text.ToUpper(); if (labelStyle.Wrap) text = text.Replace(' ', '\n'); matrix.TranslatePrepend(labelStyle.Translation.X, labelStyle.Translation.Y); matrix.RotatePrepend(labelStyle.Rotation); matrix.ScalePrepend(labelStyle.Scale.Width, labelStyle.Scale.Height); g.MultiplyTransform(matrix, XMatrixOrder.Prepend); XSize size = g.MeasureString(text, font); size.Width *= 2; // prevent cut-off e.g. when rotated XRect bounds = new XRect(-size.Width / 2, -size.Height / 2, size.Width, size.Height); tf.DrawString(text, font, brush, bounds); } }