Exemple #1
0
        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();
        }
Exemple #9
0
        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();
        }