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); } }
internal void DrawName(AbstractGraphics graphics, RectangleF rect, AbstractFont font, AbstractBrush textBrush, LabelStyle labelStyle) { if (graphics == null) { throw new ArgumentNullException(nameof(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 (graphics.Save()) { graphics.TranslateTransform(pos.X, pos.Y); graphics.ScaleTransform(1.0f / Astrometrics.ParsecScaleX, 1.0f / Astrometrics.ParsecScaleY); graphics.RotateTransform(-labelStyle.Rotation); // Rotate it RenderUtil.DrawString(graphics, str, font, textBrush, 0, 0); } } } }
internal void Paint(AbstractGraphics graphics, Color dotColor, AbstractBrush labelBrush, AbstractFont labelFont) { if (graphics == null) { throw new ArgumentNullException(nameof(graphics)); } Point pt = Astrometrics.LocationToCoordinates(Location); using (graphics.Save()) { graphics.TranslateTransform(pt.X, pt.Y); graphics.ScaleTransform(1.0f / Astrometrics.ParsecScaleX, 1.0f / Astrometrics.ParsecScaleY); const float radius = 3; AbstractBrush brush = new AbstractBrush(dotColor); AbstractPen pen = new AbstractPen(dotColor); graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.DrawEllipse(pen, brush, -radius / 2, -radius / 2, radius, radius); RenderUtil.TextFormat format; if (LabelBiasX > 0) { format = LabelBiasY < 0 ? RenderUtil.TextFormat.BottomLeft : LabelBiasY > 0 ? RenderUtil.TextFormat.TopLeft : RenderUtil.TextFormat.MiddleLeft; } else if (LabelBiasX < 0) { format = LabelBiasY < 0 ? RenderUtil.TextFormat.BottomRight : LabelBiasY > 0 ? RenderUtil.TextFormat.TopRight : RenderUtil.TextFormat.MiddleRight; } else { format = LabelBiasY < 0 ? RenderUtil.TextFormat.BottomCenter : LabelBiasY > 0 ? RenderUtil.TextFormat.TopCenter : RenderUtil.TextFormat.Center; } float y = (LabelBiasY * radius / 2); float x = (LabelBiasX * radius / 2); RenderUtil.DrawString(graphics, Name, labelFont, labelBrush, x, y, format); } }
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); // TODO: Accomodate wrapping //SizeF size = graphics.MeasureString( str, font, bounds.Size); XSize size = graphics.MeasureString(str, font); graphics.TranslateTransform(-size.Width / 2, -size.Height / 2); // Center the text //graphics.TextRenderingHint = TextRenderingHint.AntiAlias; RectangleF textBounds = new RectangleF(0, 0, (float)size.Width, (float)size.Height * 2); // *2 or it gets cut off at high sizes graphics.DrawString(str, font, textBrush, textBounds, RenderUtil.StringFormatTopCenter); } } } }
public void Paint(XGraphics graphics, RectangleF rect, MapOptions options, Color dotColor, XBrush labelBrush, XFont labelFont) { if (graphics == null) { throw new ArgumentNullException("graphics"); } Point pt = Astrometrics.LocationToCoordinates(Location); using (RenderUtil.SaveState(graphics)) { graphics.SmoothingMode = XSmoothingMode.HighSpeed; graphics.TranslateTransform(pt.X, pt.Y); graphics.ScaleTransform(1.0f / Astrometrics.ParsecScaleX, 1.0f / Astrometrics.ParsecScaleY); const float radius = 3; XBrush brush = new XSolidBrush(dotColor); XPen pen = new XPen(dotColor); graphics.DrawEllipse(brush, -radius / 2, -radius / 2, radius, radius); graphics.SmoothingMode = XSmoothingMode.HighQuality; graphics.DrawEllipse(pen, -radius / 2, -radius / 2, radius, radius); XStringFormat format = (LabelBiasX == -1) ? RenderUtil.StringFormatTopRight : (LabelBiasX == 1) ? RenderUtil.StringFormatTopLeft : RenderUtil.StringFormatTopCenter; XSize size = graphics.MeasureString(Name, labelFont); XPoint pos = new XPoint(0, 0); //pos.X += ( LabelBiasX * radius / 2 ) + ( -size.Width * ( 1 - LabelBiasX ) / 2.0f ); pos.Y += (LabelBiasY * radius / 2) + (-size.Height * (1 - LabelBiasY) / 2.0f); pos.X += (LabelBiasX * radius / 2); //pos.Y += ( LabelBiasY * radius / 2 ); graphics.DrawString(Name, labelFont, labelBrush, pos.X, pos.Y, format); } }
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 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 BorderPath(Border border, Sector sector, PathUtil.PathType type) { RenderUtil.HexEdges(type, out float[] edgeX, out float[] edgeY); int lengthEstimate = border.Path.Count() * 3; List <PointF> points = new List <PointF>(lengthEstimate); List <byte> types = new List <byte>(lengthEstimate); LinkedList <LinkedList <PointF> > segments = new LinkedList <LinkedList <PointF> >(); LinkedList <PointF> currentSegment = new LinkedList <PointF>(); // Based on http://dotclue.org/t20/sec2pdf - J Greely rocks my world. int checkFirst = 0; int checkLast = 5; Hex startHex = Hex.Empty; bool startHexVisited = false; foreach (Hex hex in border.Path) { checkLast = checkFirst + 5; if (startHexVisited && hex == startHex) { // I'm in the starting hex, and I've been // there before, so stop testing at neighbor // 5, no matter what checkLast = 5; // degenerate case, entering for third time if (checkFirst < 3) { break; } } else if (!startHexVisited) { startHex = hex; startHexVisited = true; // PERF: This seems costly... analyze it! PointF newPoint = Astrometrics.HexToCenter(Astrometrics.LocationToCoordinates(new Location(sector.Location, hex))); newPoint.X += edgeX[0]; newPoint.Y += edgeY[0]; // MOVETO points.Add(newPoint); types.Add((byte)PathPointType.Start); // MOVETO currentSegment.AddLast(newPoint); } PointF pt = Astrometrics.HexToCenter(Astrometrics.LocationToCoordinates(new Location(sector.Location, hex))); int i = checkFirst; for (int check = checkFirst; check <= checkLast; check++) { i = check; Hex neighbor = Astrometrics.HexNeighbor(hex, i % 6); if (border.Path.Contains(neighbor)) // TODO: Consider a hash here { break; } PointF newPoint = new PointF(pt.X + edgeX[(i + 1) % 6], pt.Y + edgeY[(i + 1) % 6]); // LINETO points.Add(newPoint); types.Add((byte)PathPointType.Line); if (hex.IsValid) { // MOVETO currentSegment.AddLast(newPoint); } else { // LINETO if (currentSegment.Count > 1) { segments.AddLast(currentSegment); } currentSegment = new LinkedList <PointF>(); currentSegment.AddLast(newPoint); } } i %= 6; // i is the direction to the next border hex, // and when we get there, we'll have come from // i + 3, so we start checking with i + 4. checkFirst = (i + 4) % 6; } if (points.First() == points.Last()) { int c = points.Count; points.RemoveAt(c - 1); types.RemoveAt(c - 1); } types[types.Count - 1] |= (byte)PathPointType.CloseSubpath; if (currentSegment.Count > 1) { segments.AddLast(currentSegment); } this.points = points.ToArray(); this.types = types.ToArray(); // If last curve segment connects to first curve segment, merge them. // Example: Imperial border in Verge. if (segments.Count >= 2 && segments.First().First() == segments.Last().Last()) { var first = segments.First(); var last = segments.Last(); segments.RemoveFirst(); first.RemoveFirst(); foreach (var point in first) { last.AddLast(point); } } curves = segments.Select(c => { if (c.First() == c.Last()) { c.RemoveLast(); return(new CurveSegment(c, true)); } else { return(new CurveSegment(c, false)); } }).ToList(); }
public BorderPath(Border border, Sector sector, PathUtil.PathType type) { float[] edgeX, edgeY; RenderUtil.HexEdges(type, out edgeX, out edgeY); int lengthEstimate = border.Path.Length * 3; List <PointF> borderPathPoints = new List <PointF>(lengthEstimate); List <byte> borderPathTypes = new List <byte>(lengthEstimate); List <PointF> clipPathPoints = new List <PointF>(lengthEstimate); List <byte> clipPathTypes = new List <byte>(lengthEstimate); List <List <PointF> > curves = new List <List <PointF> >(lengthEstimate); List <PointF> curve = new List <PointF>(lengthEstimate); // Based on http://dotclue.org/t20/sec2pdf - J Greely rocks my world. int checkFirst = 0; int checkLast = 5; int startHex = 0; bool startHexVisited = false; foreach (int hex in border.Path) { checkLast = checkFirst + 5; if (startHexVisited && hex == startHex) { // I'm in the starting hex, and I've been // there before, so stop testing at neighbor // 5, no matter what checkLast = 5; // degenerate case, entering for third time if (checkFirst < 3) { break; } } else if (!startHexVisited) { startHex = hex; startHexVisited = true; // PERF: This seems costly... analyze it! PointF newPoint = Astrometrics.HexToCenter(Astrometrics.LocationToCoordinates(new Location(sector.Location, hex))); newPoint.X += edgeX[0]; newPoint.Y += edgeY[0]; // MOVETO borderPathPoints.Add(newPoint); borderPathTypes.Add((byte)PathPointType.Start); // MOVETO clipPathPoints.Add(newPoint); clipPathTypes.Add((byte)PathPointType.Start); if (curve.Count > 1) { curves.Add(curve); curve = new List <PointF>(lengthEstimate); curve.Add(newPoint); } else { curve.Clear(); curve.Add(newPoint); } } PointF pt = Astrometrics.HexToCenter(Astrometrics.LocationToCoordinates(new Location(sector.Location, hex))); int i = checkFirst; for (int check = checkFirst; check <= checkLast; check++) { i = check; int neighbor = Astrometrics.HexNeighbor(hex, i % 6); if (Array.IndexOf <int>(border.Path, neighbor) != -1) // Consider a hash here { break; } PointF newPoint = new PointF(pt.X + edgeX[(i + 1) % 6], pt.Y + edgeY[(i + 1) % 6]); // TODO: Replace this by clipping borders to sector bounds; problem - bottom/right edges protrude // Only actually render edges within the sector //if( 1 <= ( hex / 100 ) && ( hex / 100 ) <= 32 && 1 <= ( hex % 100 ) && ( hex % 100 ) <= 40 ) { // LINETO borderPathPoints.Add(newPoint); borderPathTypes.Add((byte)PathPointType.Line); //curve.Add( newPoint ); if (Util.InRange(hex / 100, 1, Astrometrics.SectorWidth) && Util.InRange(hex % 100, 1, Astrometrics.SectorHeight)) { curve.Add(newPoint); } else { if (curve.Count > 1) { curves.Add(curve); curve = new List <PointF>(lengthEstimate); curve.Add(newPoint); } else { curve.Clear(); curve.Add(newPoint); } } } /* * else * { * // MOVETO * if( borderPathTypes[ borderPathTypes.Count - 1 ] == (byte)PathPointType.Start ) * { * // Collapse multiple MOVETOs - makes GDI+ happy * borderPathPoints[ borderPathPoints.Count - 1 ] = newPoint; * } * else * { * borderPathPoints.Add( newPoint ); * borderPathTypes.Add( (byte)PathPointType.Start ); * } * * if( curve.Count > 1 ) * { * curves.Add( curve ); * curve = new List<PointF>( lengthEstimate ); * curve.Add( newPoint ); * } * else * { * curve.Clear(); * curve.Add( newPoint ); * } * } * */ // LINETO clipPathPoints.Add(newPoint); clipPathTypes.Add((byte)PathPointType.Line); } i = i % 6; // i is the direction to the next border hex, // and when we get there, we'll have come from // i + 3, so we start checking with i + 4. checkFirst = (i + 4) % 6; } // Trim trailing MOVETOs - makes GDI+ happy while (borderPathTypes.Count > 0 && borderPathTypes[borderPathTypes.Count - 1] == (byte)PathPointType.Start) { borderPathTypes.RemoveAt(borderPathTypes.Count - 1); borderPathPoints.RemoveAt(borderPathPoints.Count - 1); } borderPathTypes[borderPathTypes.Count - 1] |= (byte)PathPointType.CloseSubpath; this.borderPathPoints = borderPathPoints.ToArray(); this.borderPathTypes = borderPathTypes.ToArray(); this.clipPathPoints = clipPathPoints.ToArray(); this.clipPathTypes = clipPathTypes.ToArray(); if (curve.Count > 1) { curves.Add(curve); } this.curvePoints = curves.Select(c => c.ToArray()).ToArray(); }