Ejemplo n.º 1
0
 public TextLine FormatLine(TextSource textSource, int firstCharIndex, double paragraphWidth,
                            TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak)
 {
     return(formatter.FormatLine(textSource, firstCharIndex, paragraphWidth, paragraphProperties, previousLineBreak));
 }
Ejemplo n.º 2
0
        public Collection <IFormattedLine> FormatLineInVisualBuffer(ITextSnapshotLine visualLine)
        {
            if (visualLine == null)
            {
                throw new ArgumentNullException(nameof(visualLine));
            }
            if (visualLine.Snapshot != TopTextSnapshot)
            {
                throw new ArgumentException();
            }

            var seqColl             = TextAndAdornmentSequencer.CreateTextAndAdornmentCollection(visualLine, visualLine.Snapshot);
            var bufferLine          = GetBufferLine(seqColl);
            var linePartsCollection = CreateLinePartsCollection(seqColl, bufferLine.ExtentIncludingLineBreak);
            var textSource          = new LinePartsTextSource(linePartsCollection);
            var lines = new Collection <IFormattedLine>();

            TextLineBreak previousLineBreak = null;
            double        autoIndent        = BaseIndentation;
            int           column            = 0;
            int           linePartsIndex    = 0;
            var           lineParts         = linePartsCollection.LineParts;

            for (int lineSegment = 0; ; lineSegment++)
            {
                var paragraphProperties = textParagraphPropertiesFactoryService?.Create(this,
                                                                                        classificationFormatMap.DefaultTextProperties,
                                                                                        TextAndAdornmentSequencer.BufferGraph.CreateMappingSpan(bufferLine.Extent, SpanTrackingMode.EdgeNegative),
                                                                                        TextAndAdornmentSequencer.BufferGraph.CreateMappingPoint(textSource.ConvertColumnToBufferPosition(column), PointTrackingMode.Negative), lineSegment)
                                          ?? defaultTextParagraphProperties;

                double paragraphWidth = WordWrapWidth == 0 ? 0 : Math.Max(1, WordWrapWidth - autoIndent - wrapGlyphWidth);

                textSource.SetMaxLineLength(MAX_LINE_LENGTH);
                var textLine = textFormatter.FormatLine(textSource, column, paragraphWidth, paragraphProperties, previousLineBreak);

                int startColumn = column;
                int length      = textLine.GetLength(textSource.EndOfLine);
                column += length;

                int linePartsEnd = linePartsIndex;
                Debug.Assert(lineParts.Count == 0 || linePartsEnd < lineParts.Count);
                while (linePartsEnd < lineParts.Count)
                {
                    var part = lineParts[linePartsEnd];
                    linePartsEnd++;
                    if (column <= part.Column + part.ColumnLength)
                    {
                        break;
                    }
                }
                linePartsEnd--;

                var startPos = textSource.ConvertColumnToBufferPosition(startColumn);
                var endPos   = textSource.ConvertColumnToBufferPosition(column);
                if (column >= textSource.Length)
                {
                    endPos       = bufferLine.ExtentIncludingLineBreak.End;
                    linePartsEnd = lineParts.Count - 1;
                }

                var lineSpan = new SnapshotSpan(startPos, endPos);
                var wpfLine  = new WpfTextViewLine(TextAndAdornmentSequencer.BufferGraph, linePartsCollection, linePartsIndex, linePartsEnd - linePartsIndex + 1, startColumn, column, bufferLine, lineSpan, visualLine.Snapshot, textLine, autoIndent, ColumnWidth);
                lines.Add(wpfLine);

                if (column >= textSource.Length)
                {
                    Debug.Assert(column == textSource.Length);
                    break;
                }
                if (startColumn == column)
                {
                    throw new InvalidOperationException();
                }

                linePartsIndex = linePartsEnd;
                while (linePartsIndex < lineParts.Count)
                {
                    var part = lineParts[linePartsIndex];
                    if (column < part.Column + part.ColumnLength)
                    {
                        break;
                    }
                    linePartsIndex++;
                }

                if (lineSegment == 0)
                {
                    autoIndent = 0;
                    var firstCharColumn = textSource.GetColumnOfFirstNonWhitespace();
                    if (firstCharColumn < column)
                    {
                        autoIndent += textLine.GetDistanceFromCharacterHit(new CharacterHit(firstCharColumn, 0));
                    }
                    autoIndent += TabSize / 2 * ColumnWidth;
                    if (autoIndent > MaxAutoIndent)
                    {
                        autoIndent = MaxAutoIndent;
                    }
                    // Base indentation should always be included
                    autoIndent += BaseIndentation;
                }

                previousLineBreak = textLine.GetTextLineBreak();
            }

            return(lines);
        }
Ejemplo n.º 3
0
        public TextLine FormatLine(TextSource textSource, int firstCharIndex, double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak)
        {
            var runs = new List <Tuple <TextRun, GlyphRun, int, double> >();

            int    index = firstCharIndex;
            double x = paragraphProperties.Indent, height = 0, baseline = 0;
            double trailWhitespaceWidth = 0;

            while (true)
            {
                var run       = textSource.GetTextRun(index);
                var textProps = run.Properties ?? paragraphProperties.DefaultTextRunProperties;
                var fontSize  = textProps.FontRenderingEmSize;
                var len       = run.Length;
                if (textProps != null)
                {
                    height   = Math.Max(height, (int)(textProps.Typeface.FontFamily.LineSpacing * fontSize));
                    baseline = Math.Max(baseline, (int)(textProps.Typeface.FontFamily.Baseline * fontSize));
                }

                if (run is TextEndOfLine || run == null)
                {
                    index += len;
                    runs.Add(Tuple.Create(run, (GlyphRun)null, 0, 0.0));
                    break;
                }
                else if (run is TextCharacters)
                {
                    var chrs       = (TextCharacters)run;
                    var charBuf    = getCharBuf(chrs.CharacterBufferReference);
                    var charOffset = getCharOffset(chrs.CharacterBufferReference);

                    GlyphTypeface gl;
                    if (!textProps.Typeface.TryGetGlyphTypeface(out gl))
                    {
                        throw new Exception("GlyphTypeface does not exists for font '" + textProps.Typeface.FontFamily + "'.");
                    }

                    ushort[] glyphIndexes  = new ushort[len];
                    double[] advanceWidths = new double[len];

                    double totalWidth      = 0;
                    int    trailWhitespace = 0;
                    trailWhitespaceWidth = 0;
                    for (int n = 0; n < len; n++)
                    {
                        var c = charBuf[charOffset + n];

                        ushort glyphIndex;
                        double width;

                        if (c == '\t')
                        {
                            glyphIndex = gl.CharacterToGlyphMap[' '];
                            width      = paragraphProperties.DefaultIncrementalTab - x % paragraphProperties.DefaultIncrementalTab;
                        }
                        else
                        {
                            if (!gl.CharacterToGlyphMap.TryGetValue(c, out glyphIndex))
                            {
                                glyphIndex = gl.CharacterToGlyphMap['?'];
                            }
                            width = gl.AdvanceWidths[glyphIndex] * fontSize;
                        }

                        glyphIndexes[n]  = glyphIndex;
                        advanceWidths[n] = width;

                        if (char.IsWhiteSpace(c))
                        {
                            trailWhitespace++;
                            trailWhitespaceWidth += width;
                        }
                        else
                        {
                            totalWidth          += trailWhitespaceWidth + width;
                            trailWhitespaceWidth = 0;
                            trailWhitespace      = 0;
                        }
                    }
                    var origin = new Point(x, 0);

                    var glyphRun = new GlyphRun(
                        gl, 0, false, fontSize, glyphIndexes, origin, advanceWidths,
                        null, null, null, null, null, null);
                    runs.Add(Tuple.Create(run, glyphRun, trailWhitespace, trailWhitespaceWidth));

                    x += totalWidth + trailWhitespaceWidth;

                    index += len;
                }
                else if (run is TextEmbeddedObject)
                {
                    var obj     = (TextEmbeddedObject)run;
                    var metrics = obj.Format(paragraphWidth - x);
                    runs.Add(Tuple.Create(run, (GlyphRun)null, 0, metrics.Width));

                    height = Math.Max(height, obj.Format(paragraphWidth - x).Height);
                    x     += metrics.Width;

                    index += len;
                }
            }

            return(new GlyphRunLine {
                entries = runs.ToArray(),
                baseline = baseline,
                width = x - trailWhitespaceWidth,
                height = height,
                mode = mode
            });
        }
Ejemplo n.º 4
0
        // ------------------------------------------------------------------
        // Create and format text line.
        //
        //      lineStartIndex - index of the first character in the line
        //      width - wrapping width of the line
        //      lineProperties - properties of the line
        //      textRunCache - run cache used by text formatter
        //      showParagraphEllipsis - true if paragraph ellipsis is shown
        //                              at the end of the line
        // ------------------------------------------------------------------
        internal void Format(int dcp, double width, TextParagraphProperties lineProperties, TextLineBreak textLineBreak, TextRunCache textRunCache, bool showParagraphEllipsis)
        {
#if TEXTPANELLAYOUTDEBUG
            TextPanelDebug.IncrementCounter("Line.Format", TextPanelDebug.Category.TextView);
#endif
            _mirror = (lineProperties.FlowDirection == FlowDirection.RightToLeft);
            _dcp    = dcp;
            _showParagraphEllipsis = showParagraphEllipsis;
            _wrappingWidth         = width;
            _line = _owner.TextFormatter.FormatLine(this, dcp, width, lineProperties, textLineBreak, textRunCache);
        }
Ejemplo n.º 5
0
 // ------------------------------------------------------------------
 // Constructor.
 //
 //      PtsContext - Context
 //      TextLineBreak - Contained line break
 // ------------------------------------------------------------------
 internal LineBreakRecord(PtsContext ptsContext, TextLineBreak textLineBreak) : base(ptsContext)
 {
     _textLineBreak = textLineBreak;
 }
Ejemplo n.º 6
0
 // Token: 0x06006866 RID: 26726 RVA: 0x001D6D10 File Offset: 0x001D4F10
 internal void Format(Line.FormattingContext ctx, int dcp, int width, int trackWidth, TextParagraphProperties lineProps, TextLineBreak textLineBreak)
 {
     this._formattingContext = ctx;
     this._dcp           = dcp;
     this._host.Context  = this;
     this._wrappingWidth = TextDpi.FromTextDpi(width);
     this._trackWidth    = TextDpi.FromTextDpi(trackWidth);
     this._mirror        = (lineProps.FlowDirection == FlowDirection.RightToLeft);
     this._indent        = lineProps.Indent;
     try
     {
         if (ctx.LineFormatLengthTarget == -1)
         {
             this._line = this._host.TextFormatter.FormatLine(this._host, dcp, this._wrappingWidth, lineProps, textLineBreak, ctx.TextRunCache);
         }
         else
         {
             this._line = this._host.TextFormatter.RecreateLine(this._host, dcp, ctx.LineFormatLengthTarget, this._wrappingWidth, lineProps, textLineBreak, ctx.TextRunCache);
         }
         this._runs = this._line.GetTextRunSpans();
         Invariant.Assert(this._runs != null, "Cannot retrieve runs collection.");
         if (this._formattingContext.MeasureMode)
         {
             List <InlineObject> list = new List <InlineObject>(1);
             int num = this._dcp;
             foreach (TextSpan <TextRun> textSpan in this._runs)
             {
                 TextRun value = textSpan.Value;
                 if (value is InlineObjectRun)
                 {
                     list.Add(new InlineObject(num, ((InlineObjectRun)value).UIElementIsland, (TextParagraph)this._paraClient.Paragraph));
                 }
                 else if (value is FloatingRun)
                 {
                     if (((FloatingRun)value).Figure)
                     {
                         this._hasFigures = true;
                     }
                     else
                     {
                         this._hasFloaters = true;
                     }
                 }
                 num += textSpan.Length;
             }
             if (list.Count == 0)
             {
                 list = null;
             }
             this.TextParagraph.SubmitInlineObjects(dcp, dcp + this.ActualLength, list);
         }
     }
     finally
     {
         this._host.Context = null;
     }
 }
Ejemplo n.º 7
0
        internal static IList <TextBreakpoint> CreateMultiple(
            TextParagraphCache paragraphCache,
            int firstCharIndex,
            int maxLineWidth,
            TextLineBreak previousLineBreak,
            IntPtr penaltyRestriction,
            out int bestFitIndex
            )
        {
            Invariant.Assert(paragraphCache != null);

            // grab full text state from paragraph cache
            FullTextState fullText = paragraphCache.FullText;

            Invariant.Assert(fullText != null);

            FormatSettings settings = fullText.TextStore.Settings;

            Invariant.Assert(settings != null);

            // update formatting parameters at line start
            settings.UpdateSettingsForCurrentLine(
                maxLineWidth,
                previousLineBreak,
                (firstCharIndex == fullText.TextStore.CpFirst)
                );

            Invariant.Assert(settings.Formatter != null);

            // acquiring LS context
            TextFormatterContext context = settings.Formatter.AcquireContext(fullText, IntPtr.Zero);

            IntPtr previousBreakRecord = IntPtr.Zero;

            if (settings.PreviousLineBreak != null)
            {
                previousBreakRecord = settings.PreviousLineBreak.BreakRecord.Value;
            }

            // need not consider marker as tab since marker does not affect line metrics and it wasnt drawn.
            fullText.SetTabs(context);

            LsBreaks lsbreaks = new LsBreaks();

            LsErr lserr = context.CreateBreaks(
                fullText.GetBreakpointInternalCp(firstCharIndex),
                previousBreakRecord,
                paragraphCache.Ploparabreak.Value,  // para breaking session
                penaltyRestriction,
                ref lsbreaks,
                out bestFitIndex
                );

            // get the exception in context before it is released
            Exception callbackException = context.CallbackException;

            // release the context
            context.Release();

            if (lserr != LsErr.None)
            {
                if (callbackException != null)
                {
                    // rethrow exception thrown in callbacks
                    throw callbackException;
                }
                else
                {
                    // throw with LS error codes
                    TextFormatterContext.ThrowExceptionFromLsError(SR.Get(SRID.CreateBreaksFailure, lserr), lserr);
                }
            }

            // keep context alive at least till here
            GC.KeepAlive(context);

            TextBreakpoint[] breakpoints = new TextBreakpoint[lsbreaks.cBreaks];

            for (int i = 0; i < lsbreaks.cBreaks; i++)
            {
                breakpoints[i] = new FullTextBreakpoint(
                    fullText,
                    firstCharIndex,
                    maxLineWidth,
                    ref lsbreaks,
                    i   // the current break
                    );
            }

            return(breakpoints);
        }
Ejemplo n.º 8
0
        // Token: 0x06006B27 RID: 27431 RVA: 0x001EEE9C File Offset: 0x001ED09C
        internal IList <TextBreakpoint> FormatLineVariants(TextParaClient textParaClient, TextParagraphCache textParagraphCache, OptimalTextSource optimalTextSource, int dcp, TextLineBreak textLineBreak, uint fswdir, int urStartLine, int durLine, bool allowHyphenation, bool clearOnLeft, bool clearOnRight, bool treatAsFirstInPara, bool treatAsLastInPara, bool suppressTopSpace, IntPtr lineVariantRestriction, out int iLineBestVariant)
        {
            base.StructuralCache.TextFormatterHost.Context = optimalTextSource;
            IList <TextBreakpoint> result = textParagraphCache.FormatBreakpoints(dcp, textLineBreak, lineVariantRestriction, TextDpi.FromTextDpi(durLine), out iLineBestVariant);

            base.StructuralCache.TextFormatterHost.Context = null;
            return(result);
        }