public static async Task <CustomTextSource4> UpdateFormattedText(ICodeView iface1) { Debug.WriteLine("Enteirng updateformattedtext " + iface1.PerformingUpdate); if (iface1.PerformingUpdate) { Debug.WriteLine("Already performing update"); return(null); } iface1.PerformingUpdate = true; iface1.Status = CodeControlStatus.Rendering; iface1.RaiseEvent(new RoutedEventArgs(RoslynCodeControl.RenderStartEvent, iface1)); var textStorePosition = 0; var linePosition = new Point(iface1.XOffset, 0); iface1.TextDestination.Children.Clear(); var line = 0; Debug.WriteLine("Calling inner update"); // ScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled; var fontFamilyFamilyName = iface1.FontFamily.FamilyNames[XmlLanguage.GetLanguage("en-US")]; Debug.WriteLine(fontFamilyFamilyName); Debug.WriteLine("OutputWidth " + iface1.OutputWidth); // not sure what to do here !! // Rectangle.Width = OutputWidth + Rectangle.StrokeThickness * 2; var emSize = iface1.FontSize; var fontWeight = iface1.FontWeight; var customTextSource4Parameters = iface1.CreateDefaultTextSourceArguments(); var mainUpdateParameters = new MainUpdateParameters(textStorePosition, line, linePosition, RoslynCodeControl.Formatter, iface1.OutputWidth, iface1.PixelsPerDip, emSize, fontFamilyFamilyName, iface1.UpdateChannel.Writer, fontWeight, iface1.DocumentPaginator, customTextSource4Parameters); await iface1.JTF2.SwitchToMainThreadAsync(); var source = await iface1.InnerUpdateAsync(mainUpdateParameters, customTextSource4Parameters); return(source); }
/// <inheritdoc /> public async Task UpdateFormattedTextAsync() { var codeView = (ICodeView)this; _debugFn?.Invoke($"Entering {nameof(UpdateFormattedTextAsync)} {codeView.PerformingUpdate}"); if (codeView.PerformingUpdate) { _debugFn?.Invoke("Already performing update"); } else { JTF.RunAsync(ReaderListenerAsync); codeView.PerformingUpdate = true; codeView.Status = CodeControlStatus.Rendering; codeView.Reset(); codeView.RaiseEvent(new RoutedEventArgs(RenderStartEvent, this)); var text = await SyntaxTree.GetTextAsync(); var o = new Point(double.NaN, 0); for (var i = 0; i < text.Lines.Count; i++) { DrawLineNumber(i, o); o.Y += LineHeight; } var textStorePosition = 0; var linePosition = new Point(codeView.XOffset, 0); codeView.TextDestination.Children.Clear(); var line = 0; _debugFn?.Invoke("Calling inner update"); // ScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled; var fontFamilyFamilyName = codeView.FontFamily.FamilyNames[XmlLanguage.GetLanguage("en-US")]; _debugFn?.Invoke(fontFamilyFamilyName); _debugFn?.Invoke("OutputWidth " + codeView.OutputWidth); // not sure what to do here !! // Rectangle.Width = OutputWidth + Rectangle.StrokeThickness * 2; var emSize = codeView.FontSize; var fontWeight = codeView.FontWeight; var customTextSource4Parameters = codeView.CreateDefaultTextSourceArguments(); var mainUpdateParameters = new MainUpdateParameters(textStorePosition, line, linePosition, CommonText.Formatter, codeView.OutputWidth, codeView.PixelsPerDip, emSize, fontFamilyFamilyName, codeView.UpdateChannel.Writer, fontWeight, null, customTextSource4Parameters, _debugFn); await JTF2.SwitchToMainThreadAsync(); SecondaryThreadTasks(); var source = codeView.InnerUpdate(mainUpdateParameters, customTextSource4Parameters); await JTF.SwitchToMainThreadAsync(); codeView.CustomTextSource = source; _debugFn?.Invoke("Return from await inner update"); codeView.PerformingUpdate = false; codeView.InitialUpdate = false; codeView.RaiseEvent(new RoutedEventArgs(RenderCompleteEvent, this)); codeView.Status = CodeControlStatus.Rendered; codeView.InsertionPoint = 0; codeView.InsertionLineNode = codeView.FindLine(0); #if false foreach (var x1 in codeView.FindLine(0).List) { for (var ci1 = x1.FirstCharInfo; ci1 != null && ci1.Value.Index < x1.Offset + x1.Length; ci1 = ci1.Next) { Debug.WriteLine($"{x1.LineNumber:D4},{ci1.Value.LineIndex:D3},{ci1.Value.Index:D6}"); } } #endif #if false var #if av = codeView.FindLine(0).Value.FirstCharInfo.List.Average(c => c.AdvanceWidth); foreach (var x1 in codeView.FindLine(0).Value.FirstCharInfo.List.GroupBy(c => c.AdvanceWidth) .Select(z => new { Width = z.Key, Count = z.Count() })) { var msg = $"{x1.Width} - {x1.Count}"; DebugFn(msg); Debug.WriteLine(msg); } Debug.WriteLine($"Average related to font size is {av/FontSize}"); #endif await UpdateRoslynPropertiesAsync(); ScrollViewer.InvalidateScrollInfo(); } }
public static unsafe CustomTextSource4 InnerUpdateAsync(MainUpdateParameters mainUpdateParameters, Func <CustomTextSource4> makeSource) { LinkedListNode <CharInfo> charInfoNode = null; const int batchLines = 100; var lineInfos0 = new LineInfo2[batchLines]; var lineInfos1 = new LineInfo2[batchLines]; var lineInfos = lineInfos0; int @switch = 0; mainUpdateParameters.DebugFn?.Invoke($"{nameof(InnerUpdateAsync)}", 5); var tf = CreateTypeface(new FontFamily(mainUpdateParameters.FaceName), FontStyles.Normal, FontStretches.Normal, mainUpdateParameters.FontWeight); var currentRendering = FontRendering.CreateInstance(mainUpdateParameters.FontSize, TextAlignment.Left, null, Brushes.Black, tf); var customTextSource4 = makeSource(); var myGroup = new DrawingGroup(); var myDc = myGroup.Open(); var genericTextParagraphProperties = new GenericTextParagraphProperties(currentRendering, mainUpdateParameters.PixelsPerDip); var runsInfos = new List <TextRunInfo>(); var allCharInfos = new LinkedList <CharInfo>(); var textStorePosition = mainUpdateParameters.TextStorePosition; var lineNo = mainUpdateParameters.LineNo; // var tasks = new List<Task>(); var linePosition = mainUpdateParameters.LinePosition; var liIndex = 0; while (textStorePosition < customTextSource4.Length) { var runCount = customTextSource4.Runs.Count; #if DEBUGTEXTSOURCE Debug.WriteLine("Runcount = " + runCount); #endif var numPages = 0; var pageBegin = new Point(0, 0); var pageEnd = new Point(0, 0); if (mainUpdateParameters.Paginate) { // ReSharper disable once PossibleInvalidOperationException pageEnd.Offset(mainUpdateParameters.PageSize.Value.Width, mainUpdateParameters.PageSize.Value.Height); } LineInfo2 lineInfo; var linePositionX = mainUpdateParameters.ParagraphWidth - linePosition.X; if (linePositionX < 0) { linePositionX = 0; } using (var myTextLine = mainUpdateParameters.TextFormatter.FormatLine(customTextSource4, textStorePosition, linePositionX, genericTextParagraphProperties, null)) { var nRuns = customTextSource4.Runs.Count - runCount; if (nRuns < 0) { throw new InvalidOperationException("NRuns is negative" + nRuns); } #if DEBUGTEXTSOURCE Debug.WriteLine("num runs for line is " + nRuns); #endif var curCharInfoNode = charInfoNode; HandleLine(allCharInfos, linePosition, myTextLine, customTextSource4, runCount, nRuns, lineNo, textStorePosition, runsInfos, curCharInfoNode, out charInfoNode, mainUpdateParameters.DebugFn); myTextLine.Draw(myDc, linePosition, InvertAxes.None); lineInfos[liIndex++] = new LineInfo2(lineNo, curCharInfoNode != null? curCharInfoNode.Next : allCharInfos.First, textStorePosition, linePosition, myTextLine.Height, myTextLine.Length); linePosition.Y += myTextLine.Height; lineNo++; // Update the index position in the text store. textStorePosition += myTextLine.Length; if (mainUpdateParameters.Paginate && linePosition.Y >= pageEnd.Y) { Debug.WriteLine($"numPages: {numPages}"); numPages++; } } #if GROUPEDDG if (lineNo > 0 && lineNo % batchLines == 0) { myDc.Close(); myGroup.Freeze(); var curUi = new UpdateInfo() { DrawingGroup = myGroup, CharInfos = allCharInfos.ToList <CharInfo>() }; await mainUpdateParameters.ChannelWriter.WriteAsync(curUi); // tasks.Add(writeAsync.AsTask()); myGroup = new DrawingGroup(); myDc = myGroup.Open(); } #else if (lineNo <= 0 || lineNo % batchLines != 0) { continue; } myDc.Close(); myGroup.Freeze(); var curUi = new UpdateInfo( myGroup, liIndex, lineInfos ); liIndex = 0; if (@switch == 0) { lineInfos = lineInfos1; @switch = 1; } else { lineInfos = lineInfos0; @switch = 0; } mainUpdateParameters.ChannelWriter.WriteAsync(curUi); myGroup = new DrawingGroup(); myDc = myGroup.Open(); #endif } customTextSource4.RunInfos = runsInfos; #if GROUPEDDG if (lineNo % 100 != 0) { myDc.Close(); myGroup.Freeze(); var curUi = new UpdateInfo() { DrawingGroup = myGroup, CharInfos = Enumerable.ToList <CharInfo>(allCharInfos), FinalBlock = true }; await mainUpdateParameters.ChannelWriter.WriteAsync(curUi); // tasks.Add(writeAsync.AsTask()); } else { myDc.Close(); } #else if (lineNo % batchLines == 0) { return(customTextSource4); } { myDc.Close(); myGroup.Freeze(); var curUi = new UpdateInfo( myGroup, liIndex, lineInfos ); mainUpdateParameters.ChannelWriter.WriteAsync(curUi); } #endif // await Task.WhenAll(tasks); return(customTextSource4); }
/// <inheritdoc /> public CustomTextSource4 InnerUpdate(MainUpdateParameters mainUpdateParameters, TextSourceInitializationParameters textSourceInitializationParameters) { return(CommonText.InnerUpdateAsync(mainUpdateParameters, () => CreateCustomTextSource4(textSourceInitializationParameters))); }