//------------------------------------------------------------------- // Calculate line advance distance. This functionality will go away // when TextFormatter will be able to handle line height/stacking. // // lineHeight - calculated line height // // Returns: Line advance distance.. //------------------------------------------------------------------- private double CalcLineAdvance(double lineHeight, LineProperties lineProperties) { return lineProperties.CalcLineAdvance(lineHeight); }
// Performs one iteration of background measure. // Background measure always works at the end of the current // line metrics array -- invalidations to prevoiusly examined // content is handled by incremental layout, synchronously. // // Returns the full content size, omitting any unanalyzed content // at the document end. private Size FullMeasureTick(double constraintWidth, LineProperties lineProperties) { Size desiredSize; TextBoxLine line = new TextBoxLine(this); int lineOffset; bool endOfParagraph; // Find the next position for this iteration. if (_lineMetrics.Count == 0) { desiredSize = new Size(); lineOffset = 0; } else { desiredSize = _contentSize; lineOffset = _lineMetrics[_lineMetrics.Count - 1].EndOffset; } // Calculate a stop time. // We limit work to just a few milliseconds per iteration // to avoid blocking the thread. DateTime stopTime; if ((ScrollBarVisibility)((Control)_host).GetValue(ScrollViewer.VerticalScrollBarVisibilityProperty) == ScrollBarVisibility.Auto) { // Workaround for bug 1766924. // When VerticalScrollBarVisiblity == Auto, there's a problem with // our interaction with ScrollViewer. Disable background layout to // mitigate the problem until we can take a real fix in v.next. // stopTime = DateTime.MaxValue; } else { stopTime = DateTime.Now.AddMilliseconds(_maxMeasureTimeMs); } // Format lines until we hit the end of document or run out of time. do { using (line) { line.Format(lineOffset, constraintWidth, constraintWidth, lineProperties, _cache.TextRunCache, _cache.TextFormatter); // This is a loop invariant, but has negligable cost. // _lineHeight = lineProperties.CalcLineAdvance(line.Height); _lineMetrics.Add(new LineRecord(lineOffset, line)); // Desired width is always max of calculated line widths. // Desired height is sum of all line heights. desiredSize.Width = Math.Max(desiredSize.Width, line.Width); desiredSize.Height += _lineHeight; lineOffset += line.Length; endOfParagraph = line.EndOfParagraph; } } while (!endOfParagraph && DateTime.Now < stopTime); if (!endOfParagraph) { // Ran out of time. Defer to background layout. SetFlags(true, Flags.BackgroundLayoutPending); this.Dispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(OnBackgroundMeasure), null); } else { // Finished the entire document. Stop background layout. SetFlags(false, Flags.BackgroundLayoutPending); } return desiredSize; }