public override IEnumerable <IHexTagSpan <HexMarkerTag> > GetTags(NormalizedHexBufferSpanCollection spans) { foreach (var span in hexViewSearchService.GetSpans(spans)) { yield return(new HexTagSpan <HexMarkerTag>(span, HexSpanSelectionFlags.Selection, searchHexMarkerTag)); } }
string GenerateHtmlFragmentCore(HexBufferLineFormatter bufferLines, NormalizedHexBufferSpanCollection spans, HexView?hexView, string delimiter, CancellationToken cancellationToken) { HexClassifier?classifier = null; try { VSTC.IClassificationFormatMap classificationFormatMap; if (!(hexView is null)) { classifier = viewClassifierAggregatorService.GetClassifier(hexView); classificationFormatMap = classificationFormatMapService.GetClassificationFormatMap(hexView); } else { classifier = spans.Count == 0 ? null : classifierAggregatorService.GetClassifier(spans[0].Buffer); classificationFormatMap = classificationFormatMapService.GetClassificationFormatMap(AppearanceCategoryConstants.HexEditor); } const int tabSize = 4; var builder = new HexHtmlBuilder(classificationFormatMap, delimiter, tabSize); if (spans.Count != 0) { Debug2.Assert(!(classifier is null)); builder.Add(bufferLines, classifier, spans, cancellationToken); } return(builder.Create()); }
public override IEnumerable <IHexTagSpan <HexMarkerTag> > GetTags(NormalizedHexBufferSpanCollection spans) { if (!highlightStructureUnderMouseCursor) { yield break; } var collection = activeToolTipInfoCollection; if (collection == null) { yield break; } foreach (var span in spans) { if (!collection.FullBufferSpan.IntersectsWith(span)) { continue; } foreach (var info in collection) { yield return(new HexTagSpan <HexMarkerTag>(info.BufferSpan, HexSpanSelectionFlags.Selection, new HexMarkerTag(info.ClassificationType))); } } }
public override string GenerateHtmlFragment(NormalizedHexBufferSpanCollection spans, HexView hexView, string delimiter, CancellationToken cancellationToken) { if (spans == null) throw new ArgumentNullException(nameof(spans)); if (hexView == null) throw new ArgumentNullException(nameof(hexView)); if (delimiter == null) throw new ArgumentNullException(nameof(delimiter)); return GenerateHtmlFragmentCore(hexView.BufferLines, spans, hexView, delimiter, cancellationToken); }
public static bool IntersectsWithButDoesNotStartAtItsEnd(this NormalizedHexBufferSpanCollection coll, HexBufferSpan bufferSpan) { foreach (var span in coll) { if (bufferSpan.End != span.Start && span.IntersectsWith(bufferSpan)) { return(true); } } return(false); }
void UpdateRange(NormalizedHexBufferSpanCollection spans) { if (spans.Count == 1 && spans[0].Start <= wpfHexView.BufferLines.BufferStart && spans[0].End >= wpfHexView.BufferLines.BufferEnd) { RemoveAllMarkerElements(); } else { RemoveMarkerElements(spans); } AddMarkerElements(spans); }
public override string GenerateHtmlFragment(NormalizedHexBufferSpanCollection spans, HexBufferLineProvider bufferLines, string delimiter, CancellationToken cancellationToken) { if (spans == null) throw new ArgumentNullException(nameof(spans)); if (bufferLines == null) throw new ArgumentNullException(nameof(bufferLines)); if (delimiter == null) throw new ArgumentNullException(nameof(delimiter)); if (spans.Count != 0 && spans[0].Buffer != bufferLines.Buffer) throw new ArgumentException(); return GenerateHtmlFragmentCore(bufferLines, spans, null, delimiter, cancellationToken); }
public override IEnumerable <IHexTagSpan <HexClassificationTag> > GetTags(NormalizedHexBufferSpanCollection spans) { foreach (var span in spans) { yield return(new HexTagSpan <HexClassificationTag>(span, HexSpanSelectionFlags.Offset, hexClassificationTags.HexOffsetTag)); yield return(new HexTagSpan <HexClassificationTag>(span, HexSpanSelectionFlags.Ascii | HexSpanSelectionFlags.AllCells, hexClassificationTags.HexAsciiTag)); yield return(new HexTagSpan <HexClassificationTag>(span, HexSpanSelectionFlags.Values | HexSpanSelectionFlags.Group0 | HexSpanSelectionFlags.AllCells, hexClassificationTags.HexValue0Tag)); yield return(new HexTagSpan <HexClassificationTag>(span, HexSpanSelectionFlags.Values | HexSpanSelectionFlags.Group1 | HexSpanSelectionFlags.AllCells, hexClassificationTags.HexValue1Tag)); } }
public bool OverlapsWith(NormalizedHexBufferSpanCollection regions) { if (disposed) throw new ObjectDisposedException(nameof(PhysicalLine)); if (regions.Count == 0) return false; if (BufferSpan.Buffer != regions[0].Buffer) throw new ArgumentException(); foreach (var r in regions) { if (r.OverlapsWith(BufferSpan)) return true; } return false; }
void RemoveMarkerElements(NormalizedHexBufferSpanCollection spans) { if (spans.Count == 0) { return; } for (int i = markerElements.Count - 1; i >= 0; i--) { var markerElement = markerElements[i]; if (spans.IntersectsWithButDoesNotStartAtItsEnd(markerElement.Span)) { var layer = markerElement.ZIndex < 0 ? negativeTextMarkerAdornmentLayer : textMarkerAdornmentLayer; layer.RemoveAdornment(markerElement); } } }
void UpdateLines(IList <HexViewLine> newOrReformattedLines) { if (newOrReformattedLines.Count == wpfHexView.HexViewLines.Count) { RemoveAllMarkerElements(); } var lineSpans = new List <HexBufferSpan>(); foreach (var line in newOrReformattedLines) { lineSpans.Add(line.BufferSpan); } var spans = new NormalizedHexBufferSpanCollection(lineSpans); UpdateRange(spans); }
public override string GenerateHtmlFragment(NormalizedHexBufferSpanCollection spans, HexView hexView, string delimiter, CancellationToken cancellationToken) { if (spans is null) { throw new ArgumentNullException(nameof(spans)); } if (hexView is null) { throw new ArgumentNullException(nameof(hexView)); } if (delimiter is null) { throw new ArgumentNullException(nameof(delimiter)); } return(GenerateHtmlFragmentCore(hexView.BufferLines, spans, hexView, delimiter, cancellationToken)); }
public void Add(HexBufferLineProvider bufferLines, HexClassifier classifier, NormalizedHexBufferSpanCollection spans, CancellationToken cancellationToken) { if (bufferLines == null) throw new ArgumentNullException(nameof(bufferLines)); if (classifier == null) throw new ArgumentNullException(nameof(classifier)); if (spans == null) throw new ArgumentNullException(nameof(spans)); if (spans.Count != 0 && spans[0].Buffer != bufferLines.Buffer) throw new ArgumentException(); var classificationSpans = new List<HexClassificationSpan>(); foreach (var span in spans) { if (spansCount > 0) htmlWriter.WriteRaw(delimiter); spansCount++; var pos = span.Start; for (;;) { classificationSpans.Clear(); var line = bufferLines.GetLineFromPosition(pos); var text = line.GetText(span); var context = new HexClassificationContext(line, line.TextSpan); classifier.GetClassificationSpans(classificationSpans, context, cancellationToken); int textPos = 0; foreach (var tagSpan in classificationSpans) { if (textPos < tagSpan.Span.Start) { WriteCss(classificationFormatMap.DefaultTextProperties); htmlWriter.WriteSpan(cssWriter.ToString(), text, textPos, tagSpan.Span.Start - textPos); } WriteCss(classificationFormatMap.GetTextProperties(tagSpan.ClassificationType)); htmlWriter.WriteSpan(cssWriter.ToString(), text, tagSpan.Span.Start, tagSpan.Span.Length); textPos = tagSpan.Span.End; } if (textPos < text.Length) { WriteCss(classificationFormatMap.DefaultTextProperties); htmlWriter.WriteSpan(cssWriter.ToString(), text, textPos, text.Length - textPos); } htmlWriter.WriteRaw("<br/>"); pos = line.BufferEnd; if (pos >= span.End) break; } } }
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)); } } } }
// Called to classify a span of data, it can only classify bytes, not characters on a line public override IEnumerable <IHexTagSpan <HexClassificationTag> > GetTags(NormalizedHexBufferSpanCollection spans) { if (spans.Count == 0) { yield break; } var ourSpan = new HexBufferSpan(spans[0].Buffer, 10, 128); foreach (var span in spans) { if (!span.IntersectsWith(ourSpan)) { continue; } // Classify both columns (values and ASCII) yield return(new HexTagSpan <HexClassificationTag>(ourSpan, HexSpanSelectionFlags.Selection, new HexClassificationTag(color2))); } }
IEnumerable <IHexTagSpan <T> > GetTags(NormalizedHexBufferSpanCollection spans) { if (spans == null) { throw new ArgumentNullException(nameof(spans)); } if (spans.Count == 0) { yield break; } foreach (var tagger in taggers) { foreach (var tagSpan in tagger.GetTags(spans)) { if (spans.IntersectsWith(tagSpan.Span)) { yield return(tagSpan); } } } }
public override string GenerateHtmlFragment(NormalizedHexBufferSpanCollection spans, HexBufferLineFormatter bufferLines, string delimiter, CancellationToken cancellationToken) { if (spans is null) { throw new ArgumentNullException(nameof(spans)); } if (bufferLines is null) { throw new ArgumentNullException(nameof(bufferLines)); } if (delimiter is null) { throw new ArgumentNullException(nameof(delimiter)); } if (spans.Count != 0 && spans[0].Buffer != bufferLines.Buffer) { throw new ArgumentException(); } return(GenerateHtmlFragmentCore(bufferLines, spans, null, delimiter, cancellationToken)); }
string GenerateHtmlFragmentCore(HexBufferLineProvider bufferLines, NormalizedHexBufferSpanCollection spans, HexView hexView, string delimiter, CancellationToken cancellationToken) { HexClassifier classifier = null; try { VSTC.IClassificationFormatMap classificationFormatMap; if (hexView != null) { classifier = viewClassifierAggregatorService.GetClassifier(hexView); classificationFormatMap = classificationFormatMapService.GetClassificationFormatMap(hexView); } else { classifier = spans.Count == 0 ? null : classifierAggregatorService.GetClassifier(spans[0].Buffer); classificationFormatMap = classificationFormatMapService.GetClassificationFormatMap(AppearanceCategoryConstants.HexEditor); } const int tabSize = 4; var builder = new HexHtmlBuilder(classificationFormatMap, delimiter, tabSize); if (spans.Count != 0) builder.Add(bufferLines, classifier, spans, cancellationToken); return builder.Create(); } finally { classifier.Dispose(); } }
public bool OverlapsWith(NormalizedHexBufferSpanCollection regions) { if (disposed) { throw new ObjectDisposedException(nameof(PhysicalLine)); } if (regions.Count == 0) { return(false); } if (BufferSpan.Buffer != regions[0].Buffer) { throw new ArgumentException(); } foreach (var r in regions) { if (r.OverlapsWith(BufferSpan)) { return(true); } } return(false); }
/// <summary> /// Creates an HTML fragment that can be copied to the clipboard /// </summary> /// <param name="spans">Spans</param> /// <param name="hexView">Hex view</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public string GenerateHtmlFragment(NormalizedHexBufferSpanCollection spans, HexView hexView, CancellationToken cancellationToken) => GenerateHtmlFragment(spans, hexView, DefaultDelimiter, cancellationToken);
public override IEnumerable <IHexTagSpan <T> > GetTags(NormalizedHexBufferSpanCollection spans, CancellationToken cancellationToken) => owner.GetTags(spans, cancellationToken);
public override IEnumerable <IHexTagSpan <T> > GetTags(NormalizedHexBufferSpanCollection spans) => owner.GetTags(spans);
public void Add(HexBufferLineFormatter bufferLines, HexClassifier classifier, NormalizedHexBufferSpanCollection spans, CancellationToken cancellationToken) { if (bufferLines == null) { throw new ArgumentNullException(nameof(bufferLines)); } if (classifier == null) { throw new ArgumentNullException(nameof(classifier)); } if (spans == null) { throw new ArgumentNullException(nameof(spans)); } if (spans.Count != 0 && spans[0].Buffer != bufferLines.Buffer) { throw new ArgumentException(); } var classificationSpans = new List <HexClassificationSpan>(); foreach (var span in spans) { if (spansCount > 0) { htmlWriter.WriteRaw(delimiter); } spansCount++; var pos = span.Start; for (;;) { classificationSpans.Clear(); var line = bufferLines.GetLineFromPosition(pos); var text = line.GetText(span); var context = new HexClassificationContext(line, line.TextSpan); classifier.GetClassificationSpans(classificationSpans, context, cancellationToken); int textPos = 0; foreach (var tagSpan in classificationSpans) { if (textPos < tagSpan.Span.Start) { WriteCss(classificationFormatMap.DefaultTextProperties); htmlWriter.WriteSpan(cssWriter.ToString(), text, textPos, tagSpan.Span.Start - textPos); } WriteCss(classificationFormatMap.GetTextProperties(tagSpan.ClassificationType)); htmlWriter.WriteSpan(cssWriter.ToString(), text, tagSpan.Span.Start, tagSpan.Span.Length); textPos = tagSpan.Span.End; } if (textPos < text.Length) { WriteCss(classificationFormatMap.DefaultTextProperties); htmlWriter.WriteSpan(cssWriter.ToString(), text, textPos, text.Length - textPos); } htmlWriter.WriteRaw("<br/>"); pos = line.BufferEnd; if (pos >= span.End) { break; } } } }
public override IEnumerable <IHexTagSpan <HexMarkerTag> > GetTags(NormalizedHexBufferSpanCollection spans) => hexToolTipService.GetTags(spans);
static HexPosition GetTotalBytes(NormalizedHexBufferSpanCollection spans) { var totalBytes = HexPosition.Zero; foreach (var span in spans) totalBytes += span.Length; return totalBytes; }
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; } } } }
void UpdateLines(IList<HexViewLine> newOrReformattedLines) { if (newOrReformattedLines.Count == wpfHexView.HexViewLines.Count) RemoveAllMarkerElements(); var lineSpans = new List<HexBufferSpan>(); foreach (var line in newOrReformattedLines) lineSpans.Add(line.BufferSpan); var spans = new NormalizedHexBufferSpanCollection(lineSpans); UpdateRange(spans); }
/// <summary> /// Returns all tags intersecting with <paramref name="spans"/>. This method is synchronous. /// </summary> /// <param name="spans">Span</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public abstract IEnumerable <IHexTagSpan <T> > GetTags(NormalizedHexBufferSpanCollection spans, CancellationToken cancellationToken);
string TryCreateHtmlText(NormalizedHexBufferSpanCollection spans) { if (spans.Count == 0) return null; // There's no way for us to cancel it so don't classify too much text var totalBytes = GetTotalBytes(spans); if (totalBytes > htmlMaxTotalBytesToCopy) return null; var cancellationToken = CancellationToken.None; return htmlBuilderService.GenerateHtmlFragment(spans, HexView, cancellationToken); }
public override IEnumerable <IHexTagSpan <HexMarkerTag> > GetTags(NormalizedHexBufferSpanCollection spans) => currentValueHighlighter.GetTags(spans);
internal IEnumerable <IHexTagSpan <HexMarkerTag> > GetTags(NormalizedHexBufferSpanCollection spans) { yield break; }
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<HexBufferSpan> GetSpans(NormalizedHexBufferSpanCollection spans) { var searchService = hexMarkerSearchService; if (searchService == null) yield break; var validSpan = wpfHexView.BufferLines.BufferSpan; int lengthLessOne = searchService.ByteCount - 1; foreach (var span in spans) { var overlap = validSpan.Overlap(span); if (overlap == null) continue; var start = validSpan.Start.Position + lengthLessOne <= overlap.Value.Start.Position ? overlap.Value.Start - lengthLessOne : validSpan.Start; var end = new HexBufferPoint(validSpan.Buffer, HexPosition.Min(overlap.Value.End.Position + lengthLessOne, validSpan.End)); foreach (var res in searchService.FindAll(HexBufferSpan.FromBounds(start, end), start, HexFindOptions.None, CancellationToken.None)) yield return res; } }
void UpdateRange(NormalizedHexBufferSpanCollection spans) { if (spans.Count == 1 && spans[0].Start <= wpfHexView.BufferLines.BufferStart && spans[0].End >= wpfHexView.BufferLines.BufferEnd) RemoveAllMarkerElements(); else RemoveMarkerElements(spans); AddMarkerElements(spans); }
/// <summary> /// Creates an HTML fragment that can be copied to the clipboard /// </summary> /// <param name="spans">Spans</param> /// <param name="hexView">Hex view</param> /// <param name="delimiter">Delimiter added between generated html strings</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public abstract string GenerateHtmlFragment(NormalizedHexBufferSpanCollection spans, HexView hexView, string delimiter, CancellationToken cancellationToken);
/// <summary> /// Gets all tags intersecting with <paramref name="spans"/>. This method is synchronous. /// </summary> /// <param name="spans">Spans</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public virtual IEnumerable <IHexTagSpan <T> > GetTags(NormalizedHexBufferSpanCollection spans, CancellationToken cancellationToken) => GetTags(spans);
void RemoveMarkerElements(NormalizedHexBufferSpanCollection spans) { if (spans.Count == 0) return; for (int i = markerElements.Count - 1; i >= 0; i--) { var markerElement = markerElements[i]; if (spans.IntersectsWithButDoesNotStartAtItsEnd(markerElement.Span)) { var layer = markerElement.ZIndex < 0 ? negativeTextMarkerAdornmentLayer : textMarkerAdornmentLayer; layer.RemoveAdornment(markerElement); } } }
List<PhysicalLine> GetValidCachedLines(NormalizedHexBufferSpanCollection regionsToInvalidate) { var lines = new List<PhysicalLine>(visiblePhysicalLines); lines.AddRange(physicalLineCache.TakeOwnership()); visiblePhysicalLines.Clear(); // Common enough that it's worth checking bool invalidateAll = false; if (regionsToInvalidate.Count == 1) { var r = regionsToInvalidate[0]; if (r.Start <= BufferLines.BufferStart && r.End >= BufferLines.BufferEnd) invalidateAll = true; } if (invalidateAll) { foreach (var line in lines) line.Dispose(); lines.Clear(); return lines; } var bufferLines = BufferLines; for (int i = lines.Count - 1; i >= 0; i--) { var line = lines[i]; bool remove = line.BufferLines != bufferLines || line.OverlapsWith(regionsToInvalidate); if (remove) { line.Dispose(); lines.RemoveAt(i); } else line.UpdateIsLastLine(); } return lines; }
/// <summary> /// Creates an HTML fragment that can be copied to the clipboard /// </summary> /// <param name="spans">Spans</param> /// <param name="bufferLines">Buffer lines provider</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public string GenerateHtmlFragment(NormalizedHexBufferSpanCollection spans, HexBufferLineFormatter bufferLines, CancellationToken cancellationToken) => GenerateHtmlFragment(spans, bufferLines, DefaultDelimiter, cancellationToken);
/// <summary> /// Creates an HTML fragment that can be copied to the clipboard /// </summary> /// <param name="spans">Spans</param> /// <param name="hexView">Hex view</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public string GenerateHtmlFragment(NormalizedHexBufferSpanCollection spans, HexView hexView, CancellationToken cancellationToken) => GenerateHtmlFragment(spans, hexView, DefaultDelimiter, cancellationToken);
/// <summary> /// Creates an HTML fragment that can be copied to the clipboard /// </summary> /// <param name="spans">Spans</param> /// <param name="hexView">Hex view</param> /// <param name="delimiter">Delimiter added between generated html strings</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public abstract string GenerateHtmlFragment(NormalizedHexBufferSpanCollection spans, HexView hexView, string delimiter, CancellationToken cancellationToken);
public abstract IEnumerable <IHexTagSpan <HexSpaceNegotiatingAdornmentTag> > GetTags(NormalizedHexBufferSpanCollection spans);
void DisplayLines(HexBufferPoint bufferPosition, double verticalDistance, VSTE.ViewRelativePosition relativeTo, double viewportWidthOverride, double viewportHeightOverride, DisplayHexLineOptions options, double? newViewportTop) { if (IsClosed) throw new InvalidOperationException(); var oldBufferLines = hexBufferLineFormatter; var oldHexBufferLineFormatterOptions = hexBufferLineFormatterOptions; Debug.Assert(oldBufferLines != null); bool raiseBufferLinesChangedEvent = false; bool revalidateBufferPosition = false; canvas.Dispatcher.VerifyAccess(); if (bufferPosition.Buffer != Buffer) throw new ArgumentException(); if (relativeTo != VSTE.ViewRelativePosition.Top && relativeTo != VSTE.ViewRelativePosition.Bottom) throw new ArgumentOutOfRangeException(nameof(relativeTo)); if (viewportHeightOverride < 0 || double.IsNaN(viewportHeightOverride)) throw new ArgumentOutOfRangeException(nameof(viewportHeightOverride)); if (viewportWidthOverride < 0 || double.IsNaN(viewportWidthOverride)) throw new ArgumentOutOfRangeException(nameof(viewportWidthOverride)); bool invalidateAllLines = false; if (recreateHexBufferLineFormatter) invalidateAllLines = true; if (viewportWidthOverride != lastViewportWidth || viewportWidthOverride != lastFormattedLineSourceViewportWidth) { invalidateAllLines = true; lastViewportWidth = viewportWidthOverride; } // Make sure the scheduled method doesn't try to call this method delayLayoutLinesInProgress = false; if (invalidateAllLines) { invalidatedRegions.Clear(); invalidatedRegions.Add(new HexBufferSpan(new HexBufferPoint(Buffer, 0), new HexBufferPoint(Buffer, HexPosition.MaxEndPosition))); } var regionsToInvalidate = new NormalizedHexBufferSpanCollection(invalidatedRegions); invalidatedRegions.Clear(); if (invalidatedRegions.Capacity > 100) invalidatedRegions.TrimExcess(); if (invalidateAllLines || formattedLineSourceIsInvalidated) { CreateFormattedLineSource(viewportWidthOverride); formattedLineSourceIsInvalidated = false; recreateHexBufferLineFormatter = true; } // This one depends on FormattedLineSource and must be created afterwards if (recreateHexBufferLineFormatter) { recreateHexBufferLineFormatter = false; raiseBufferLinesChangedEvent = true; if ((options & DisplayHexLineOptions.CanRecreateBufferLines) != 0) { // It's safe to invalidate it here since we were called by the dispatcher and // not by user code. hexBufferLineFormatter = null; // Once the new instance gets created, the input bufferPosition could be invalid // because start and/or end got updated. Re-validate it before creating new lines. revalidateBufferPosition = true; } else { // Don't re-create it here. That can lead to exceptions if Start/End positions get // updated and bufferPosition becomes invalid. New BufferLines' IsValidPosition() throws. // It's recreated with a short delay after raising LayoutChanged. } } var lineTransformProvider = LineTransformProvider; if (InLayout) throw new InvalidOperationException(); inLayout = true; var oldVisibleLines = new HashSet<HexViewLine>(wpfHexViewLineCollection == null ? (IEnumerable<HexViewLine>)Array.Empty<HexViewLine>() : wpfHexViewLineCollection); wpfHexViewLineCollection?.Invalidate(); var layoutHelper = new LayoutHelper(BufferLines, lineTransformProvider, newViewportTop ?? 0, oldVisibleLines, GetValidCachedLines(regionsToInvalidate), FormattedLineSource); if (revalidateBufferPosition) { if (bufferPosition < BufferLines.BufferStart) { bufferPosition = BufferLines.BufferStart; relativeTo = VSTE.ViewRelativePosition.Top; verticalDistance = 0; } else if (bufferPosition > BufferLines.BufferEnd) { bufferPosition = BufferLines.BufferEnd; relativeTo = VSTE.ViewRelativePosition.Bottom; verticalDistance = 0; } } layoutHelper.LayoutLines(bufferPosition, relativeTo, verticalDistance, ViewportLeft, viewportWidthOverride, viewportHeightOverride); visiblePhysicalLines.AddRange(layoutHelper.AllVisiblePhysicalLines); wpfHexViewLineCollection = new WpfHexViewLineCollectionImpl(this, layoutHelper.AllVisibleLines); if (!InLayout) throw new InvalidOperationException(); inLayout = false; textLayer.AddVisibleLines(layoutHelper.AllVisibleLines); var newOrReformattedLines = layoutHelper.NewOrReformattedLines.ToArray(); var translatedLines = layoutHelper.TranslatedLines.ToArray(); if (layoutHelper.NewViewportTop != viewportTop) { viewportTop = layoutHelper.NewViewportTop; Canvas.SetTop(normalAdornmentLayerCollection, -viewportTop); } if ((options & DisplayHexLineOptions.CanRecreateBufferLines) != 0) { if (raiseBufferLinesChangedEvent) RaiseBufferLinesChanged(oldBufferLines); } else if (raiseBufferLinesChangedEvent && oldBufferLines == hexBufferLineFormatter) { var newOptions = GetHexBufferLineFormatterOptions(); if (!newOptions.Equals(oldHexBufferLineFormatterOptions)) { canvas.Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() => { if (oldBufferLines == hexBufferLineFormatter) { hexBufferLineFormatter = null; var newBufferLines = BufferLines; RaiseBufferLinesChanged(oldBufferLines); var line = wpfHexViewLineCollection.FirstVisibleLine; verticalDistance = line.Top - ViewportTop; bufferPosition = line.BufferStart; if (bufferPosition < BufferLines.BufferStart) bufferPosition = BufferLines.BufferStart; else if (bufferPosition > BufferLines.BufferEnd) bufferPosition = BufferLines.BufferEnd; DisplayLines(bufferPosition, verticalDistance, VSTE.ViewRelativePosition.Top, ViewportWidth, ViewportHeight, DisplayHexLineOptions.CanRecreateBufferLines, ViewportTop); } })); } } // Raise this event after BufferLinesChanged event. BufferLinesChanged is more low level and // various code could use cached positions in LayoutChanged handlers (eg. the caret will use // its cached position). If this event is raised afterwards, they have a chance to re-validate // their cached values. RaiseLayoutChanged(viewportWidthOverride, viewportHeightOverride, newOrReformattedLines, translatedLines); }
public override IEnumerable <IHexTagSpan <HexSpaceNegotiatingAdornmentTag> > GetTags(NormalizedHexBufferSpanCollection spans) { if (wpfHexView.IsClosed) { yield break; } foreach (var span in spans) { foreach (var tagSpan in tagAggregator.GetTags(span)) { 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(tagSpan.Span, 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 HexTagSpan <HexSpaceNegotiatingAdornmentTag>(tagSpan.Span, tagSpan.Flags, tag)); } } }
public abstract IEnumerable <IHexTagSpan <HexMarkerTag> > GetTags(NormalizedHexBufferSpanCollection spans);
public override IEnumerable <IHexTagSpan <HexSpaceNegotiatingAdornmentTag> > GetTags(NormalizedHexBufferSpanCollection spans) => intraTextAdornmentService.GetTags(spans);
/// <summary> /// Creates an HTML fragment that can be copied to the clipboard /// </summary> /// <param name="spans">Spans</param> /// <param name="bufferLines">Buffer lines provider</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public string GenerateHtmlFragment(NormalizedHexBufferSpanCollection spans, HexBufferLineFormatter bufferLines, CancellationToken cancellationToken) => GenerateHtmlFragment(spans, bufferLines, DefaultDelimiter, cancellationToken);
public abstract IEnumerable<HexBufferSpan> GetSpans(NormalizedHexBufferSpanCollection spans);