Exemple #1
0
        public static void AddLine(XGraphicsPath path, LineSegment segment, Random random, bool straightEdges)
        {
            if (Settings.HandDrawn && !straightEdges)
              {
            var dx = segment.End.X - segment.Start.X;
            var dy = segment.End.Y - segment.Start.Y;
            var distance = (float) Math.Sqrt(dx*dx + dy*dy);
            var points = random.Next(Math.Max(3, (int) (distance/15)), Math.Max(6, (int) (distance/8)));
            var lines = points - 1;
            var last = segment.Start;
            for (var line = 0; line < lines; ++line)
            {
              Vector next;
              if (line == 0)
              {
            next = last;
              }
              else if (line == lines - 1)
              {
            next = segment.End;
              }
              else
              {
            var fraction = line/(float) (lines - 1);
            var x = segment.Start.X + (segment.End.X - segment.Start.X)*fraction;
            var y = segment.Start.Y + (segment.End.Y - segment.Start.Y)*fraction;

            x += random.Next(-1, 2);
            y += random.Next(-1, 2);
            next = new Vector(x, y);
              }

              path.AddLine(last.ToPointF(), next.ToPointF());
              last = next;
            }
              }
              else
              {
            path.AddLine(segment.Start.ToPointF(), segment.End.ToPointF());
              }
        }
Exemple #2
0
 public float DistanceFromLineSegment(LineSegment line)
 {
     return DistanceFromLineSegment(line, this);
 }
Exemple #3
0
        public static float DistanceFromLineSegment(LineSegment line, Vector pos)
        {
            var delta = line.End - line.Start;
            var direction = Vector.Normalize(delta);

            float distanceAlongSegment = Vector.Dot(pos, direction) - Vector.Dot(line.Start, direction);
            Vector nearest;
            if (distanceAlongSegment < 0)
            {
                nearest = line.Start;
            }
            else if (distanceAlongSegment > delta.Length)
            {
                nearest = line.End;
            }
            else
            {
                nearest = line.Start + distanceAlongSegment * direction;
            }

            return Vector.Distance(nearest, pos);
        }
Exemple #4
0
        /// <summary>
        ///   Split the given line segment if it crosses line segments we've already drawn.
        /// </summary>
        /// <param name="lineSegment">The line segment to consider.</param>
        /// <param name="context">The context in which we've been drawing line segments.</param>
        /// <param name="newSegments">
        ///   The results of splitting the given line segment, if any. Call with a reference to a null
        ///   list.
        /// </param>
        /// <returns>True if the line segment was split and newSegments now exists and contains line segments; false otherwise.</returns>
        private bool Split(LineSegment lineSegment, DrawingContext context, ref List<LineSegment> newSegments)
        {
            foreach (var previousSegment in context.LinesDrawn)
              {
            var amount = Math.Max(1, Settings.LineWidth)*3;
            List<LineSegmentIntersect> intersects;
            if (lineSegment.Intersect(previousSegment, true, out intersects))
            {
              foreach (var intersect in intersects)
              {
            switch (intersect.Type)
            {
              case LineSegmentIntersectType.MidPointA:
                var one = new LineSegment(lineSegment.Start, intersect.Position);
                if (one.Shorten(amount))
                {
                  if (!Split(one, context, ref newSegments))
                  {
                    if (newSegments == null)
                    {
                      newSegments = new List<LineSegment>();
                    }
                    newSegments.Add(one);
                  }
                }
                var two = new LineSegment(intersect.Position, lineSegment.End);
                if (two.Forshorten(amount))
                {
                  if (!Split(two, context, ref newSegments))
                  {
                    if (newSegments == null)
                    {
                      newSegments = new List<LineSegment>();
                    }
                    newSegments.Add(two);
                  }
                }
                break;

              case LineSegmentIntersectType.StartA:
                if (lineSegment.Forshorten(amount))
                {
                  if (!Split(lineSegment, context, ref newSegments))
                  {
                    if (newSegments == null)
                    {
                      newSegments = new List<LineSegment>();
                    }
                    newSegments.Add(lineSegment);
                  }
                }
                break;

              case LineSegmentIntersectType.EndA:
                if (lineSegment.Shorten(amount))
                {
                  if (!Split(lineSegment, context, ref newSegments))
                  {
                    if (newSegments == null)
                    {
                      newSegments = new List<LineSegment>();
                    }
                    newSegments.Add(lineSegment);
                  }
                }
                break;
            }

            // don't check other intersects;
            // we've already split this line, and tested the parts for further intersects.
            return newSegments != null;
              }
            }
              }
              return false;
        }
Exemple #5
0
        private void Annotate(XGraphics graphics, Palette palette, List<LineSegment> lineSegments)
        {
            if (lineSegments.Count == 0)
            return;

              if (!string.IsNullOrEmpty(StartText))
              {
            Annotate(graphics, palette, lineSegments[0], m_startText, StringAlignment.Near, GetSourceRoom()?.Shape);
              }

              if (!string.IsNullOrEmpty(EndText))
              {
            Annotate(graphics, palette, lineSegments[lineSegments.Count - 1], m_endText, StringAlignment.Far, GetTargetRoom()?.Shape);
              }

              if (!string.IsNullOrEmpty(MidText))
              {
            var totalLength = lineSegments.Sum(lineSegment => lineSegment.Length);
            var middle = totalLength/2;
            foreach (var lineSegment in lineSegments)
            {
              var length = lineSegment.Length;
              if (middle > length)
              {
            middle -= length;
              }
              else
              {
            middle /= length;
            var pos = lineSegment.Start + lineSegment.Delta*middle;
            var fakeSegment = new LineSegment(pos - lineSegment.Delta*Numeric.Small, pos + lineSegment.Delta*Numeric.Small);
            Annotate(graphics, palette, fakeSegment, m_midText, StringAlignment.Center);
            break;
              }
            }
              }
        }
Exemple #6
0
        private static void Annotate(XGraphics graphics, Palette palette, LineSegment lineSegment, TextBlock text, StringAlignment alignment, RoomShape? shape = RoomShape.SquareCorners)
        {
            Vector point;
              var delta = lineSegment.Delta;
              switch (alignment)
              {
            case StringAlignment.Near:
            default:
              point = lineSegment.Start;
              delta.Negate();
              break;
            case StringAlignment.Center:
              point = lineSegment.Mid;
              break;
            case StringAlignment.Far:
              point = lineSegment.End;
              break;
              }

              var bounds = new Rect(point, Vector.Zero);
              bounds.Inflate(Settings.TextOffsetFromConnection);

              var angle = (float) -(Math.Atan2(delta.Y, delta.X)/Math.PI*180.0);
              var compassPoint = CompassPoint.East;
              if (Numeric.InRange(angle, 0, 45))
              {
            compassPoint = CompassPoint.NorthWest;
              }
              else if (Numeric.InRange(angle, 45, 90))
              {
            compassPoint = CompassPoint.SouthEast;
              }
              else if (Numeric.InRange(angle, 90, 135))
              {
            compassPoint = CompassPoint.SouthWest;
              }
              else if (Numeric.InRange(angle, 135, 180))
              {
            compassPoint = CompassPoint.NorthEast;
              }
              else if (Numeric.InRange(angle, 0, -45))
              {
            compassPoint = CompassPoint.NorthEast;
              }
              else if (Numeric.InRange(angle, -45, -90))
              {
            compassPoint = CompassPoint.NorthEast;
              }
              else if (Numeric.InRange(angle, -90, -135))
              {
            compassPoint = CompassPoint.NorthWest;
              }
              else if (Numeric.InRange(angle, -135, -180))
              {
            compassPoint = CompassPoint.SouthEast;
              }

              var pos = bounds.GetCorner(compassPoint);
              var format = new XStringFormat();
              Drawing.SetAlignmentFromCardinalOrOrdinalDirection(format, compassPoint);
              if (alignment == StringAlignment.Center && Numeric.InRange(angle, -10, 10))
              {
            // HACK: if the line segment is pretty horizontal and we're drawing mid-line text,
            // move text below the line to get it out of the way of any labels at the ends,
            // and center the text so it fits onto a line between two proximal rooms.
            pos = bounds.GetCorner(CompassPoint.South);
            format.Alignment = XStringAlignment.Center;
            format.LineAlignment = XLineAlignment.Near;
              }

              if (!Settings.DebugDisableTextRendering)
            text.Draw(graphics, Settings.LineFont, palette.LineTextBrush, pos, Vector.Zero, format);
        }
Exemple #7
0
        public override void PreDraw(DrawingContext context)
        {
            var topLeft = InnerBounds.GetCorner(CompassPoint.NorthWest);
            var topRight = InnerBounds.GetCorner(CompassPoint.NorthEast);
            var bottomLeft = InnerBounds.GetCorner(CompassPoint.SouthWest);
            var bottomRight = InnerBounds.GetCorner(CompassPoint.SouthEast);

            var top = new LineSegment(topLeft, topRight);
            var right = new LineSegment(topRight, bottomRight);
            var bottom = new LineSegment(bottomRight, bottomLeft);
            var left = new LineSegment(bottomLeft, topLeft);

            context.LinesDrawn.Add(top);
            context.LinesDrawn.Add(right);
            context.LinesDrawn.Add(bottom);
            context.LinesDrawn.Add(left);
        }
Exemple #8
0
 public bool IntersectsWith(Rect rect)
 {
     if (rect.Contains(Start) || rect.Contains(End))
     {
         return true;
     }
     var a = new LineSegment(new Vector(rect.Left, rect.Top), new Vector(rect.Right, rect.Top));
     var b = new LineSegment(new Vector(rect.Right, rect.Top), new Vector(rect.Right, rect.Bottom));
     var c = new LineSegment(new Vector(rect.Right, rect.Bottom), new Vector(rect.Left, rect.Bottom));
     var d = new LineSegment(new Vector(rect.Left, rect.Bottom), new Vector(rect.Left, rect.Top));
     List<LineSegmentIntersect> intersects;
     if (Intersect(a, false, out intersects) || Intersect(b, false, out intersects) || Intersect(c, false, out intersects) || Intersect(d, false, out intersects))
     {
         return true;
     }
     return false;
 }
Exemple #9
0
        public override void Draw(XGraphics graphics, Palette palette, DrawingContext context)
        {
            Random random = new Random(Name.GetHashCode());

            var topLeft = InnerBounds.GetCorner(CompassPoint.NorthWest);
            var topRight = InnerBounds.GetCorner(CompassPoint.NorthEast);
            var bottomLeft = InnerBounds.GetCorner(CompassPoint.SouthWest);
            var bottomRight = InnerBounds.GetCorner(CompassPoint.SouthEast);

            var top = new LineSegment(topLeft, topRight);
            var right = new LineSegment(topRight, bottomRight);
            var bottom = new LineSegment(bottomRight, bottomLeft);
            var left = new LineSegment(bottomLeft, topLeft);

            context.LinesDrawn.Add(top);
            context.LinesDrawn.Add(right);
            context.LinesDrawn.Add(bottom);
            context.LinesDrawn.Add(left);

            var brush = context.Selected ? palette.BorderBrush : palette.FillBrush;

            if (!Settings.DebugDisableLineRendering)
            {
                var path = palette.Path();
                Drawing.AddLine(path, top, random);
                Drawing.AddLine(path, right, random);
                Drawing.AddLine(path, bottom, random);
                Drawing.AddLine(path, left, random);
                graphics.DrawPath(brush, path);

                if (IsDark)
                {
                    var state = graphics.Save();
                    graphics.IntersectClip(path);
                    brush = context.Selected ? palette.FillBrush : palette.BorderBrush;
                    graphics.DrawPolygon(brush, new PointF[] { topRight.ToPointF(), new PointF(topRight.X - Settings.DarknessStripeSize, topRight.Y), new PointF(topRight.X, topRight.Y + Settings.DarknessStripeSize) }, XFillMode.Alternate);
                    graphics.Restore(state);
                }

                graphics.DrawPath(palette.BorderPen, path);
            }

            var font = Settings.LargeFont;
            brush = context.Selected ? palette.FillBrush : palette.LargeTextBrush;
            Rect textBounds = InnerBounds;
            textBounds.Inflate(-5, -5);

            if (textBounds.Width > 0 && textBounds.Height > 0)
            {
                m_name.Draw(graphics, font, brush, textBounds.Position, textBounds.Size, XStringFormats.Center);
            }

            var expandedBounds = InnerBounds;
            expandedBounds.Inflate(Settings.ObjectListOffsetFromRoom, Settings.ObjectListOffsetFromRoom);
            var drawnObjectList = false;

            font = Settings.SmallFont;
            brush = palette.SmallTextBrush;

            if (!string.IsNullOrEmpty(Objects))
            {
                XStringFormat format = new XStringFormat();
                Vector pos = expandedBounds.GetCorner(m_objectsPosition);
                if (!Drawing.SetAlignmentFromCardinalOrOrdinalDirection(format, m_objectsPosition))
                {
                    // object list appears inside the room below its name
                    format.LineAlignment = XLineAlignment.Far;
                    format.Alignment = XStringAlignment.Near;
                    //format.Trimming = StringTrimming.EllipsisCharacter;
                    //format.FormatFlags = StringFormatFlags.LineLimit;
                    var height = InnerBounds.Height / 2 - font.Height / 2;
                    var bounds = new Rect(InnerBounds.Left + Settings.ObjectListOffsetFromRoom, InnerBounds.Bottom - height, InnerBounds.Width - Settings.ObjectListOffsetFromRoom, height - Settings.ObjectListOffsetFromRoom);
                    brush = context.Selected ? palette.FillBrush : brush;
                    if (bounds.Width > 0 && bounds.Height > 0)
                    {
                        m_objects.Draw(graphics, font, brush, bounds.Position, bounds.Size, format);
                    }
                    drawnObjectList = true;
                }
                else if (m_objectsPosition == CompassPoint.North || m_objectsPosition == CompassPoint.South)
                {
                    pos.X += Settings.ObjectListOffsetFromRoom;
                }

                if (!drawnObjectList)
                {
                    m_objects.Draw(graphics, font, brush, pos, Vector.Zero, format);
                }
            }
        }
Exemple #10
0
        public bool Intersect(LineSegment a, LineSegment b, bool ignoreEndPointIntersects, out List<LineSegmentIntersect> intersects)
        {
            float ua = (b.End.X - b.Start.X) * (a.Start.Y - b.Start.Y) - (b.End.Y - b.Start.Y) * (a.Start.X - b.Start.X);
            float ub = (a.End.X - a.Start.X) * (a.Start.Y - b.Start.Y) - (a.End.Y - a.Start.Y) * (a.Start.X - b.Start.X);
            float denominator = (b.End.Y - b.Start.Y) * (a.End.X - a.Start.X) - (b.End.X - b.Start.X) * (a.End.Y - a.Start.Y);
            intersects = null;
            const float small = 0.01f;

            if (Math.Abs(denominator) <= small)
            {
                if (Math.Abs(ua) <= small && Math.Abs(ub) <= small)
                {
                    // lines are coincident:
                    // lacking other algorithms which actually work,
                    // roll some expensive distance tests to find intersection points
                    if (a.Start.DistanceFromLineSegment(b) <= small)
                    {
                        intersects = new List<LineSegmentIntersect>();
                        intersects.Add(new LineSegmentIntersect(LineSegmentIntersectType.StartA, a.Start));
                    }
                    if (a.End.DistanceFromLineSegment(b) <= small)
                    {
                        if (intersects == null) intersects = new List<LineSegmentIntersect>();
                        intersects.Add(new LineSegmentIntersect(LineSegmentIntersectType.EndA, a.End));
                    }
                    if (b.Start.DistanceFromLineSegment(a) <= small)
                    {
                        if (intersects == null) intersects = new List<LineSegmentIntersect>();
                        intersects.Add(new LineSegmentIntersect(LineSegmentIntersectType.MidPointA, b.Start));
                    }
                    if (b.End.DistanceFromLineSegment(a) <= small)
                    {
                        if (intersects == null) intersects = new List<LineSegmentIntersect>();
                        intersects.Add(new LineSegmentIntersect(LineSegmentIntersectType.MidPointA, b.End));
                    }
                }
            }
            else
            {
                ua /= denominator;
                ub /= denominator;

                if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)
                {
                    LineSegmentIntersectType type = LineSegmentIntersectType.MidPointA;
                    if (ua <= small)
                    {
                        type = LineSegmentIntersectType.StartA;
                    }
                    else if (1 - ua <= small)
                    {
                        type = LineSegmentIntersectType.EndA;
                    }
                    intersects = new List<LineSegmentIntersect>();
                    intersects.Add(new LineSegmentIntersect(type, a.Start + new Vector(ua * (a.End.X - a.Start.X), ua * (a.End.Y - a.Start.Y))));
                }
            }

            if (intersects != null && ignoreEndPointIntersects)
            {
                for (int index = 0; index < intersects.Count; ++index)
                {
                    var intersect = intersects[index];
                    if (intersect.Position.Distance(a.Start) <= small ||
                        intersect.Position.Distance(b.Start) <= small ||
                        intersect.Position.Distance(a.End) <= small ||
                        intersect.Position.Distance(b.End) <= small)
                    {
                        intersects.RemoveAt(index);
                        --index;
                    }
                }
            }

            return intersects != null;
        }
Exemple #11
0
 /// <summary>
 /// Find the intersection point(s) between two line segments, if any.
 /// </summary>
 /// <param name="other">The other line segment.</param>
 /// <returns>A list of one or more intersections, or null if the line segments do not intersect.</returns>
 public bool Intersect(LineSegment other, bool ignoreEndPointIntersects, out List<LineSegmentIntersect> intersects)
 {
     return Intersect(this, other, ignoreEndPointIntersects, out intersects);
 }
Exemple #12
0
        public static void AddLine(XGraphicsPath path, LineSegment segment, Random random)
        {
            if (Settings.HandDrawn)
            {
                float dx = segment.End.X - segment.Start.X;
                float dy = segment.End.Y - segment.Start.Y;
                float distance = (float)Math.Sqrt(dx * dx + dy * dy);
                int points = random.Next(Math.Max(3, (int)(distance / 15)), Math.Max(6, (int)(distance / 8)));
                int lines = points - 1;
                Vector last = segment.Start;
                for (int line = 0; line < lines; ++line)
                {
                    Vector next;
                    if (line == 0)
                    {
                        next = last;
                    }
                    else if (line == lines - 1)
                    {
                        next = segment.End;
                    }
                    else
                    {
                        float fraction = (float)line / (float)(lines - 1);
                        float x = segment.Start.X + (segment.End.X - segment.Start.X) * fraction;
                        float y = segment.Start.Y + (segment.End.Y - segment.Start.Y) * fraction;

                        x += random.Next(-1, 2);
                        y += random.Next(-1, 2);
                        next = new Vector(x, y);
                    }

                    path.AddLine(last.ToPointF(), next.ToPointF());
                    last = next;
                }
            }
            else
            {
                path.AddLine(segment.Start.ToPointF(), segment.End.ToPointF());
            }
        }
Exemple #13
0
        public override void PreDraw(DrawingContext context)
        {
            var topLeft = InnerBounds.GetCorner(CompassPoint.NorthWest);
            var topRight = InnerBounds.GetCorner(CompassPoint.NorthEast);
            var bottomLeft = InnerBounds.GetCorner(CompassPoint.SouthWest);
            var bottomRight = InnerBounds.GetCorner(CompassPoint.SouthEast);

            var topCenter = InnerBounds.GetCorner(CompassPoint.North);
            var rightCenter = InnerBounds.GetCorner(CompassPoint.East);
            var bottomCenter = InnerBounds.GetCorner(CompassPoint.South);
            var leftCenter = InnerBounds.GetCorner(CompassPoint.West);

            var top = new LineSegment(topLeft, topRight);
            var right = new LineSegment(topRight, bottomRight);
            var bottom = new LineSegment(bottomRight, bottomLeft);
            var left = new LineSegment(bottomLeft, topLeft);

            var halfTopRight = new LineSegment(topCenter, topRight);
            var halfBottomRight = new LineSegment(bottomRight, bottomCenter);
            var centerVertical = new LineSegment(bottomCenter, topCenter);

            var centerHorizontal = new LineSegment(leftCenter, rightCenter);
            var halfRightBottom = new LineSegment(rightCenter, bottomRight);
            var halfLeftBottom = new LineSegment(bottomLeft, leftCenter);

            var slantUp = new LineSegment(bottomLeft, topRight);
            var slantDown = new LineSegment(bottomRight, topLeft);

            context.LinesDrawn.Add(top);
            context.LinesDrawn.Add(right);
            context.LinesDrawn.Add(bottom);
            context.LinesDrawn.Add(left);
        }
Exemple #14
0
        public override void Draw(XGraphics graphics, Palette palette, DrawingContext context)
        {
            Random random = new Random(Name.GetHashCode());

            var topLeft = InnerBounds.GetCorner(CompassPoint.NorthWest);
            var topRight = InnerBounds.GetCorner(CompassPoint.NorthEast);
            var bottomLeft = InnerBounds.GetCorner(CompassPoint.SouthWest);
            var bottomRight = InnerBounds.GetCorner(CompassPoint.SouthEast);

            var topCenter = InnerBounds.GetCorner(CompassPoint.North);
            var rightCenter = InnerBounds.GetCorner(CompassPoint.East);
            var bottomCenter = InnerBounds.GetCorner(CompassPoint.South);
            var leftCenter = InnerBounds.GetCorner(CompassPoint.West);

            var top = new LineSegment(topLeft, topRight);
            var right = new LineSegment(topRight, bottomRight);
            var bottom = new LineSegment(bottomRight, bottomLeft);
            var left = new LineSegment(bottomLeft, topLeft);

            var halfTopRight = new LineSegment(topCenter, topRight);
            var halfBottomRight = new LineSegment(bottomRight, bottomCenter);
            var centerVertical = new LineSegment(bottomCenter, topCenter);

            var centerHorizontal = new LineSegment(leftCenter, rightCenter);
            var halfRightBottom = new LineSegment(rightCenter, bottomRight);
            var halfLeftBottom = new LineSegment(bottomLeft, leftCenter);

            var slantUp = new LineSegment(bottomLeft, topRight);
            var slantDown = new LineSegment(bottomRight, topLeft);

            context.LinesDrawn.Add(top);
            context.LinesDrawn.Add(right);
            context.LinesDrawn.Add(bottom);
            context.LinesDrawn.Add(left);

            var brush = context.Selected ? palette.BorderBrush : palette.FillBrush;
            // Room specific fill brush (White shows global color)
            if (RoomFill != ColorTranslator.FromHtml("White") && RoomFill != ColorTranslator.FromHtml("#FFFFFF")) { brush = new SolidBrush(RoomFill); }

            if (!Settings.DebugDisableLineRendering)
            {

                var path = palette.Path();
                Drawing.AddLine(path, top, random);
                Drawing.AddLine(path, right, random);
                Drawing.AddLine(path, bottom, random);
                Drawing.AddLine(path, left, random);
                graphics.DrawPath(brush, path);

                // Second fill for room specific colors with a split option
                if (SecondFill != ColorTranslator.FromHtml("White") && SecondFill != ColorTranslator.FromHtml("#FFFFFF"))
                {
                    // Set the second fill color
                    brush = new SolidBrush(SecondFill);

                    // Define the second path based on the second fill location
                    var secondPath = palette.Path();
                    switch (SecondFillLocation)
                    {
                        case "Bottom":
                            Drawing.AddLine(secondPath, centerHorizontal, random);
                            Drawing.AddLine(secondPath, halfRightBottom, random);
                            Drawing.AddLine(secondPath, bottom, random);
                            Drawing.AddLine(secondPath, halfLeftBottom, random);
                            break;
                        case "BottomRight":
                            Drawing.AddLine(secondPath, slantUp, random);
                            Drawing.AddLine(secondPath, right, random);
                            Drawing.AddLine(secondPath, bottom, random);
                            break;
                        case "Right":
                            Drawing.AddLine(secondPath, halfTopRight, random);
                            Drawing.AddLine(secondPath, right, random);
                            Drawing.AddLine(secondPath, halfBottomRight, random);
                            Drawing.AddLine(secondPath, centerVertical, random);
                            break;
                        case "TopRight":
                            Drawing.AddLine(secondPath, top, random);
                            Drawing.AddLine(secondPath, right, random);
                            Drawing.AddLine(secondPath, slantDown, random);
                            break;
                        default:
                            break;
                    }
                    // Draw the second fill over the first
                    graphics.DrawPath(brush, secondPath);
                }

                if (IsDark)
                {
                    var state = graphics.Save();
                    graphics.IntersectClip(path);
                    brush = context.Selected ? palette.FillBrush : palette.BorderBrush;
                    // Room specific fill brush (White shows global color)
                    if (RoomBorder != ColorTranslator.FromHtml("White") && RoomBorder != ColorTranslator.FromHtml("#FFFFFF")) { brush = new SolidBrush(RoomBorder); }
                    graphics.DrawPolygon(brush, new PointF[] { topRight.ToPointF(), new PointF(topRight.X - Settings.DarknessStripeSize, topRight.Y), new PointF(topRight.X, topRight.Y + Settings.DarknessStripeSize) }, XFillMode.Alternate);
                    graphics.Restore(state);
                }

                if (RoomBorder == ColorTranslator.FromHtml("White") || RoomBorder == ColorTranslator.FromHtml("#FFFFFF"))
                {
                    graphics.DrawPath(palette.BorderPen, path);
                }
                else
                {
                    var RoomBorderPen = new Pen(RoomBorder, Settings.LineWidth);
                    RoomBorderPen.StartCap = LineCap.Round;
                    RoomBorderPen.EndCap = LineCap.Round;
                    graphics.DrawPath(RoomBorderPen, path);
                }
            }

            var font = Settings.LargeFont;
            brush = context.Selected ? palette.FillBrush : palette.LargeTextBrush;
            // Room specific fill brush (White shows global color)
            if (RoomLargeText != ColorTranslator.FromHtml("White") && RoomLargeText != ColorTranslator.FromHtml("#FFFFFF")) { brush = new SolidBrush(RoomLargeText); }

            Rect textBounds = InnerBounds;
            textBounds.Inflate(-5, -5);

            if (textBounds.Width > 0 && textBounds.Height > 0)
            {
                m_name.Draw(graphics, font, brush, textBounds.Position, textBounds.Size, XStringFormats.Center);
            }

            var expandedBounds = InnerBounds;
            expandedBounds.Inflate(Settings.ObjectListOffsetFromRoom, Settings.ObjectListOffsetFromRoom);
            var drawnObjectList = false;

            font = Settings.SmallFont;
            brush = palette.SmallTextBrush;
            // Room specific fill brush (White shows global color)
            if (RoomSmallText != ColorTranslator.FromHtml("White") && RoomSmallText != ColorTranslator.FromHtml("#FFFFFF")) { brush = new SolidBrush(RoomSmallText); }

            if (!string.IsNullOrEmpty(Objects))
            {
                XStringFormat format = new XStringFormat();
                Vector pos = expandedBounds.GetCorner(m_objectsPosition);
                if (!Drawing.SetAlignmentFromCardinalOrOrdinalDirection(format, m_objectsPosition))
                {
                    // object list appears inside the room below its name
                    format.LineAlignment = XLineAlignment.Far;
                    format.Alignment = XStringAlignment.Near;
                    //format.Trimming = StringTrimming.EllipsisCharacter;
                    //format.FormatFlags = StringFormatFlags.LineLimit;
                    var height = InnerBounds.Height / 2 - font.Height / 2;
                    var bounds = new Rect(InnerBounds.Left + Settings.ObjectListOffsetFromRoom, InnerBounds.Bottom - height, InnerBounds.Width - Settings.ObjectListOffsetFromRoom, height - Settings.ObjectListOffsetFromRoom);
                    brush = context.Selected ? palette.FillBrush : brush;
                    if (bounds.Width > 0 && bounds.Height > 0)
                    {
                        m_objects.Draw(graphics, font, brush, bounds.Position, bounds.Size, format);
                    }
                    drawnObjectList = true;
                }
                else if (m_objectsPosition == CompassPoint.North || m_objectsPosition == CompassPoint.South)
                {
                    pos.X += Settings.ObjectListOffsetFromRoom;
                }

                if (!drawnObjectList)
                {
                    m_objects.Draw(graphics, font, brush, pos, Vector.Zero, format);
                }
            }
        }