/// <summary> /// Gets the overlap with <paramref name="span"/> or null if there's none /// </summary> /// <param name="span">Span</param> /// <returns></returns> public HexSpan?Overlap(HexSpan span) { var newStart = HexPosition.Max(Start, span.Start); var newEnd = HexPosition.Min(End, span.End); if (newStart < newEnd) { return(FromBounds(newStart, newEnd)); } return(null); }
TextAndHexSpan Create(HexCellCollection collection, HexCell first, HexCell last, HexBufferSpan bufferSpan) { var firstCellSpan = first.FullSpan; var lastCellSpan = last.FullSpan; var startPos = HexPosition.MaxEndPosition; var endPos = HexPosition.Zero; for (int i = first.Index; i <= last.Index; i++) { var cell = collection[i]; if (!cell.HasData) { continue; } startPos = HexPosition.Min(startPos, cell.BufferStart); endPos = HexPosition.Max(endPos, cell.BufferEnd); } var resultBufferSpan = startPos <= endPos ? new HexBufferSpan(new HexBufferPoint(Buffer, startPos), new HexBufferPoint(Buffer, endPos)) : bufferSpan; return(new TextAndHexSpan(VST.Span.FromBounds(firstCellSpan.Start, lastCellSpan.End), resultBufferSpan)); }
static HexSpan[] Normalize(IEnumerable <HexSpan> spans) { if (spans == null) { throw new ArgumentNullException(nameof(spans)); } var list = new List <HexSpan>(spans); if (list.Count <= 1) { return(list.ToArray()); } list.Sort(HexSpanComparer.Instance); int index = 0; var start = list[0].Start; var end = list[0].End; for (int i = 1; i < list.Count; i++) { var span = list[i]; if (end < span.Start) { list[index++] = HexSpan.FromBounds(start, end); start = span.Start; end = span.End; } else { end = HexPosition.Max(end, span.End); } } list[index++] = HexSpan.FromBounds(start, end); var ary = new HexSpan[index]; list.CopyTo(0, ary, 0, ary.Length); return(ary); }
IEnumerable <TextAndHexSpan> GetTextAndHexSpans(bool isColumnPresent, HexCellCollection collection, HexBufferSpan span, HexSpanSelectionFlags flags, VST.Span visibleSpan, VST.Span fullSpan) { if (span.IsDefault) { throw new ArgumentException(); } if (span.Buffer != Buffer) { throw new ArgumentException(); } if (!isColumnPresent) { yield break; } var overlapSpan = BufferSpan.Overlap(span); if (overlapSpan == null) { yield break; } if ((flags & (HexSpanSelectionFlags.Group0 | HexSpanSelectionFlags.Group1)) != 0) { bool group0 = (flags & HexSpanSelectionFlags.Group0) != 0; bool group1 = (flags & HexSpanSelectionFlags.Group1) != 0; IEnumerable <HexCell> cells; if ((flags & HexSpanSelectionFlags.AllCells) != 0) { cells = collection.GetCells(); overlapSpan = BufferSpan; } else if ((flags & HexSpanSelectionFlags.AllVisibleCells) != 0) { cells = collection.GetVisibleCells(); overlapSpan = BufferSpan; } else { cells = collection.GetCells(overlapSpan.Value); } HexCell firstCell = null; HexCell lastCell = null; foreach (var cell in cells) { if (!((cell.GroupIndex == 0 && group0) || (cell.GroupIndex == 1 && group1))) { continue; } if (firstCell == null) { firstCell = cell; lastCell = cell; } else if (lastCell.Index + 1 == cell.Index && lastCell.GroupIndex == cell.GroupIndex) { lastCell = cell; } else { yield return(Create(collection, firstCell, lastCell, overlapSpan.Value)); firstCell = lastCell = cell; } } if (firstCell != null) { yield return(Create(collection, firstCell, lastCell, overlapSpan.Value)); } yield break; } if ((flags & HexSpanSelectionFlags.AllVisibleCells) != 0) { yield return(new TextAndHexSpan(visibleSpan, BufferSpan)); yield break; } if ((flags & HexSpanSelectionFlags.AllCells) != 0) { yield return(new TextAndHexSpan(fullSpan, BufferSpan)); yield break; } if ((flags & HexSpanSelectionFlags.OneValue) != 0) { foreach (var cell in collection.GetCells(overlapSpan.Value)) { if (!cell.HasData) { continue; } var cellSpan = cell.GetSpan(flags); yield return(new TextAndHexSpan(cellSpan, new HexBufferSpan(Buffer, cell.BufferSpan))); } } else { int textStart = int.MaxValue; int textEnd = int.MinValue; var posStart = HexPosition.MaxValue; var posEnd = HexPosition.MinValue; foreach (var cell in collection.GetCells(overlapSpan.Value)) { if (!cell.HasData) { continue; } var cellSpan = cell.GetSpan(flags); textStart = Math.Min(textStart, cellSpan.Start); textEnd = Math.Max(textEnd, cellSpan.End); posStart = HexPosition.Min(posStart, cell.BufferStart); posEnd = HexPosition.Max(posEnd, cell.BufferEnd); } if (textStart > textEnd || posStart > posEnd) { yield break; } yield return(new TextAndHexSpan(VST.Span.FromBounds(textStart, textEnd), new HexBufferSpan(Buffer, HexSpan.FromBounds(posStart, posEnd)))); } }