IEnumerable <IHexTextTagSpan <T> > GetLineTags(HexTaggerContext context) { foreach (var tagger in taggers) { foreach (var tagSpan in tagger.GetTags(context)) { yield return(tagSpan); } } }
IEnumerable <IHexTextTagSpan <T> > GetLineTags(HexTaggerContext context, CancellationToken cancellationToken) { foreach (var tagger in taggers) { foreach (var tagSpan in tagger.GetTags(context, cancellationToken)) { yield return(tagSpan); } } }
internal IEnumerable <IHexTextTagSpan <HexMarkerTag> > GetTags(HexTaggerContext context) { if (wpfHexView.IsClosed) { yield break; } if (!enabled) { yield break; } Debug.Assert(savedValue != null); if (savedValue == null) { yield break; } var cells = (savedValue.Column == HexColumnType.Values ? context.Line.ValueCells : context.Line.AsciiCells).GetVisibleCells(); var markerTag = savedValue.Column == HexColumnType.Values ? valueCellMarkerTag : asciiCellMarkerTag; // PERF: Select more than one cell if there are multiple consecutive cells with the same value. // Improves perf when selecting a common value, eg. 00. HexCell startCell = null; HexCell lastCell = null; foreach (var cell in cells) { if (!savedValue.HasSameValueAs(context.Line, cell)) { continue; } if (startCell == null) { startCell = lastCell = cell; } else if (lastCell.Index + 1 != cell.Index) { yield return(new HexTextTagSpan <HexMarkerTag>(VST.Span.FromBounds(startCell.CellSpan.Start, lastCell.CellSpan.End), markerTag)); startCell = lastCell = cell; } else { lastCell = cell; } } if (startCell != null) { yield return(new HexTextTagSpan <HexMarkerTag>(VST.Span.FromBounds(startCell.CellSpan.Start, lastCell.CellSpan.End), markerTag)); } }
IEnumerable <HexGlyphTag> GetGlyphTags(WpfHexViewLine line) { foreach (var tagSpan in tagAggregator.GetTags(line.BufferSpan)) { if (line.IntersectsBufferSpan(tagSpan.Span)) { yield return(tagSpan.Tag); } } var taggerContext = new HexTaggerContext(line.BufferLine, line.BufferLine.TextSpan); foreach (var tagSpan in tagAggregator.GetLineTags(taggerContext)) { yield return(tagSpan.Tag); } }
IEnumerable <IHexTextTagSpan <T> > GetAllTags(HexTaggerContext context, CancellationToken?cancellationToken) { if (context.IsDefault) { throw new ArgumentException(); } var span = context.Line.BufferSpan; var spans = new NormalizedHexBufferSpanCollection(span); var textSpan = context.LineSpan; foreach (var tagger in taggers) { var tags = cancellationToken != null?tagger.GetTags(spans, cancellationToken.Value) : tagger.GetTags(spans); foreach (var tagSpan in tags) { var intersection = span.Intersection(tagSpan.Span); if (intersection == null) { continue; } foreach (var info in context.Line.GetSpans(intersection.Value, tagSpan.Flags)) { var vs = textSpan.Intersection(info.TextSpan); if (vs != null) { yield return(new HexTextTagSpan <T>(vs.Value, tagSpan.Tag)); } } } var textTags = cancellationToken != null?tagger.GetTags(context, cancellationToken.Value) : tagger.GetTags(context); foreach (var tagSpan in textTags) { var intersection = textSpan.Intersection(tagSpan.Span); if (intersection != null) { yield return(new HexTextTagSpan <T>(intersection.Value, tagSpan.Tag)); } } } }
public override IEnumerable <IHexTextTagSpan <HexSpaceNegotiatingAdornmentTag> > GetLineTags(HexTaggerContext context) { if (wpfHexView.IsClosed) { yield break; } var taggerContext = new HexTaggerContext(context.Line, context.LineSpan); foreach (var tagSpan in tagAggregator.GetLineTags(taggerContext)) { var uiElem = tagSpan.Tag.Adornment; double topSpace = tagSpan.Tag.TopSpace ?? 0; double bottomSpace = tagSpan.Tag.BottomSpace ?? 0; double textHeight = tagSpan.Tag.TextHeight ?? (Filter(uiElem.DesiredSize.Height) - (topSpace + bottomSpace)); var adornmentInfo = new AdornmentTagInfo(context.Line.BufferSpan, uiElem, tagSpan); var tag = new HexSpaceNegotiatingAdornmentTag(Filter(uiElem.DesiredSize.Width), topSpace, tagSpan.Tag.Baseline ?? textHeight * 0.75, textHeight, bottomSpace, tagSpan.Tag.Affinity ?? VST.PositionAffinity.Predecessor, adornmentInfo, providerTag); adornmentInfo.Tag = tag; yield return(new HexTextTagSpan <HexSpaceNegotiatingAdornmentTag>(tagSpan.Span, tag)); } }
public override IEnumerable <IHexTextTagSpan <T> > GetAllTags(HexTaggerContext context, CancellationToken cancellationToken) => owner.GetAllTags(context, cancellationToken);
public override IEnumerable <IHexTextTagSpan <T> > GetAllTags(HexTaggerContext context) => owner.GetAllTags(context, null);
void GetClassificationSpansCore(List <HexClassificationSpan> result, HexClassificationContext context, CancellationToken?cancellationToken) { if (context.IsDefault) { throw new ArgumentException(); } var textSpan = context.LineSpan; var list = new List <HexClassificationSpan>(); var taggerContext = new HexTaggerContext(context.Line, context.LineSpan); var tags = cancellationToken != null?hexTagAggregator.GetAllTags(taggerContext, cancellationToken.Value) : hexTagAggregator.GetAllTags(taggerContext); foreach (var tagSpan in tags) { var overlap = textSpan.Overlap(tagSpan.Span); if (overlap != null) { list.Add(new HexClassificationSpan(overlap.Value, tagSpan.Tag.ClassificationType)); } } if (list.Count <= 1) { if (list.Count == 1) { result.Add(list[0]); } return; } list.Sort(HexClassificationSpanComparer.Instance); // Common case if (!HasOverlaps(list)) { result.AddRange(Merge(list)); return; } int min = 0; int minOffset = textSpan.Start; var newList = new List <HexClassificationSpan>(); var ctList = new List <VSTC.IClassificationType>(); while (min < list.Count) { while (min < list.Count && minOffset >= list[min].Span.End) { min++; } if (min >= list.Count) { break; } var cspan = list[min]; minOffset = Math.Max(minOffset, cspan.Span.Start); int end = cspan.Span.End; ctList.Clear(); ctList.Add(cspan.ClassificationType); for (int i = min + 1; i < list.Count; i++) { cspan = list[i]; int cspanStart = cspan.Span.Start; if (cspanStart > minOffset) { if (cspanStart < end) { end = cspanStart; } break; } int cspanEnd = cspan.Span.End; if (minOffset >= cspanEnd) { continue; } if (cspanEnd < end) { end = cspanEnd; } if (!ctList.Contains(cspan.ClassificationType)) { ctList.Add(cspan.ClassificationType); } } Debug.Assert(minOffset < end); var ct = ctList.Count == 1 ? ctList[0] : classificationTypeRegistryService.CreateTransientClassificationType(ctList); newList.Add(new HexClassificationSpan(VST.Span.FromBounds(minOffset, end), ct)); minOffset = end; } Debug.Assert(!HasOverlaps(newList)); result.AddRange(Merge(newList)); return; }
public override IEnumerable <IHexTextTagSpan <HexSpaceNegotiatingAdornmentTag> > GetTags(HexTaggerContext context) => intraTextAdornmentService.GetLineTags(context);
public abstract IEnumerable <IHexTextTagSpan <HexSpaceNegotiatingAdornmentTag> > GetLineTags(HexTaggerContext context);
public override IEnumerable <IHexTextTagSpan <HexMarkerTag> > GetTags(HexTaggerContext context) => currentValueHighlighter.GetTags(context);
void AddMarkerElements(NormalizedHexBufferSpanCollection spans) { foreach (var tag in tagAggregator.GetTags(spans)) { if (tag.Tag?.Type == null) { continue; } if (!tag.Span.IntersectsWith(wpfHexView.HexViewLines.FormattedSpan)) { continue; } var markerElement = TryCreateMarkerElement(tag.Span, tag.Flags, tag.Tag); if (markerElement == null) { continue; } var layer = markerElement.ZIndex < 0 ? negativeTextMarkerAdornmentLayer : textMarkerAdornmentLayer; bool added = layer.AddAdornment(VSTE.AdornmentPositioningBehavior.TextRelative, markerElement.Span, null, markerElement, onRemovedDelegate); if (added) { markerElements.Add(markerElement); } } var formattedEnd = wpfHexView.HexViewLines.FormattedSpan.End; foreach (var span in spans) { var overlap = wpfHexView.HexViewLines.FormattedSpan.Overlap(span); if (overlap == null) { continue; } var pos = overlap.Value.Start; for (;;) { var line = wpfHexView.WpfHexViewLines.GetWpfHexViewLineContainingBufferPosition(pos); Debug.Assert(line != null); if (line != null) { var taggerContext = new HexTaggerContext(line.BufferLine, line.BufferLine.TextSpan); foreach (var tag in tagAggregator.GetLineTags(taggerContext)) { if (tag.Tag?.Type == null) { continue; } var markerElement = TryCreateMarkerElement(line, tag.Span, tag.Tag); if (markerElement == null) { continue; } var layer = markerElement.ZIndex < 0 ? negativeTextMarkerAdornmentLayer : textMarkerAdornmentLayer; bool added = layer.AddAdornment(VSTE.AdornmentPositioningBehavior.TextRelative, markerElement.Span, null, markerElement, onRemovedDelegate); if (added) { markerElements.Add(markerElement); } } } pos = line.BufferEnd; if (pos > overlap.Value.End || pos >= formattedEnd) { break; } } } }
public override IEnumerable <IHexTextTagSpan <HexToolTipStructureSpanTag> > GetTags(HexTaggerContext context) { yield break; }
// Called to classify a view line, any character on the line can be classified public override IEnumerable <IHexTextTagSpan <HexClassificationTag> > GetTags(HexTaggerContext context) { // Highlight every 16th line if (context.Line.LineNumber.ToUInt64() % 16 == 0) { yield return(new HexTextTagSpan <HexClassificationTag>(context.LineSpan, new HexClassificationTag(color1))); } // If there are too many zeroes, change the color of the line int zeroes = 0; for (int i = 0; i < context.Line.HexBytes.Length; i++) { if (context.Line.HexBytes.TryReadByte(i) == 0) { zeroes++; } } if (zeroes >= context.Line.HexBytes.Length / 3) { yield return(new HexTextTagSpan <HexClassificationTag>(context.LineSpan, new HexClassificationTag(color4))); } }
public override IEnumerable <IHexTextTagSpan <HexClassificationTag> > GetTags(HexTaggerContext context) { var allValid = context.Line.HexBytes.AllValid; if (allValid == null) { foreach (var cell in context.Line.ValueCells.GetVisibleCells()) { if (!IsValid(cell, context.Line)) { yield return(new HexTextTagSpan <HexClassificationTag>(cell.FullSpan, hexClassificationTags.HexErrorTag)); } } foreach (var cell in context.Line.AsciiCells.GetVisibleCells()) { if (!IsValid(cell, context.Line)) { yield return(new HexTextTagSpan <HexClassificationTag>(cell.FullSpan, hexClassificationTags.HexErrorTag)); } } } else if (!allValid.Value) { yield return(new HexTextTagSpan <HexClassificationTag>(context.Line.GetValuesSpan(onlyVisibleCells: true), hexClassificationTags.HexErrorTag)); yield return(new HexTextTagSpan <HexClassificationTag>(context.Line.GetAsciiSpan(onlyVisibleCells: true), hexClassificationTags.HexErrorTag)); } }
public override IEnumerable <IHexTextTagSpan <HexMarkerTag> > GetTags(HexTaggerContext context) { yield break; }
public override IEnumerable <IHexTextTagSpan <HexClassificationTag> > GetTags(HexTaggerContext context) { // Minimize color switches between columns: colorize the space between eg. OFFSET/VALUES and // VALUES/ASCII. This results in a small speed up displaying the lines. var columnOrder = context.Line.ColumnOrder; const HexColumnType INVALID_COLUMN = (HexColumnType)(-1); var prevColumnType = INVALID_COLUMN; for (int i = 0; i < columnOrder.Count; i++) { var columnType = columnOrder[i]; if (!context.Line.IsColumnPresent(columnType)) { continue; } if (prevColumnType != INVALID_COLUMN) { // Don't prefer VALUES column since it has two group colors var columnToUse = prevColumnType != HexColumnType.Values ? prevColumnType : columnType; HexClassificationTag tag; switch (columnToUse) { case HexColumnType.Offset: tag = hexClassificationTags.HexOffsetTag; break; case HexColumnType.Ascii: tag = hexClassificationTags.HexAsciiTag; break; case HexColumnType.Values: Debug.Fail("Should never happen"); tag = hexClassificationTags.HexValue0Tag; break; default: throw new InvalidOperationException(); } var start = context.Line.GetSpan(prevColumnType, onlyVisibleCells: false).End; var end = context.Line.GetSpan(columnType, onlyVisibleCells: false).Start; if (start < end) { yield return(new HexTextTagSpan <HexClassificationTag>(VST.Span.FromBounds(start, end), tag)); } } prevColumnType = columnType; } var allValid = context.Line.HexBytes.AllValid; if (allValid == null) { foreach (var cell in context.Line.ValueCells.GetVisibleCells()) { if (!IsValid(cell, context.Line)) { yield return(new HexTextTagSpan <HexClassificationTag>(cell.FullSpan, hexClassificationTags.HexErrorTag)); } } foreach (var cell in context.Line.AsciiCells.GetVisibleCells()) { if (!IsValid(cell, context.Line)) { yield return(new HexTextTagSpan <HexClassificationTag>(cell.FullSpan, hexClassificationTags.HexErrorTag)); } } } else if (!allValid.Value) { yield return(new HexTextTagSpan <HexClassificationTag>(context.Line.GetValuesSpan(onlyVisibleCells: true), hexClassificationTags.HexErrorTag)); yield return(new HexTextTagSpan <HexClassificationTag>(context.Line.GetAsciiSpan(onlyVisibleCells: true), hexClassificationTags.HexErrorTag)); } }