Ejemplo n.º 1
0
 void PerformVisualElementConstruction(VisualLineElementGenerator[] generators)
 {
     TextDocument document = this.Document;
     int offset = FirstDocumentLine.Offset;
     int currentLineEnd = offset + FirstDocumentLine.Length;
     LastDocumentLine = FirstDocumentLine;
     int askInterestOffset = 0; // 0 or 1
     while (offset + askInterestOffset <= currentLineEnd) {
         int textPieceEndOffset = currentLineEnd;
         foreach (VisualLineElementGenerator g in generators) {
             g.cachedInterest = g.GetFirstInterestedOffset(offset + askInterestOffset);
             if (g.cachedInterest != -1) {
                 if (g.cachedInterest < offset)
                     throw new ArgumentOutOfRangeException(g.GetType().Name + ".GetFirstInterestedOffset",
                                                           g.cachedInterest,
                                                           "GetFirstInterestedOffset must not return an offset less than startOffset. Return -1 to signal no interest.");
                 if (g.cachedInterest < textPieceEndOffset)
                     textPieceEndOffset = g.cachedInterest;
             }
         }
         Debug.Assert(textPieceEndOffset >= offset);
         if (textPieceEndOffset > offset) {
             int textPieceLength = textPieceEndOffset - offset;
             elements.Add(new VisualLineText(this, textPieceLength));
             offset = textPieceEndOffset;
         }
         // If no elements constructed / only zero-length elements constructed:
         // do not asking the generators again for the same location (would cause endless loop)
         askInterestOffset = 1;
         foreach (VisualLineElementGenerator g in generators) {
             if (g.cachedInterest == offset) {
                 VisualLineElement element = g.ConstructElement(offset);
                 if (element != null) {
                     elements.Add(element);
                     if (element.DocumentLength > 0) {
                         // a non-zero-length element was constructed
                         askInterestOffset = 0;
                         offset += element.DocumentLength;
                         if (offset > currentLineEnd) {
                             DocumentLine newEndLine = document.GetLineByOffset(offset);
                             currentLineEnd = newEndLine.Offset + newEndLine.Length;
                             this.LastDocumentLine = newEndLine;
                             if (currentLineEnd < offset) {
                                 throw new InvalidOperationException(
                                     "The VisualLineElementGenerator " + g.GetType().Name +
                                     " produced an element which ends within the line delimiter");
                             }
                         }
                         break;
                     }
                 }
             }
         }
     }
 }
Ejemplo n.º 2
0
        internal void ConstructVisualElements(ITextRunConstructionContext context, VisualLineElementGenerator[] generators)
        {
            Debug.Assert(phase == LifetimePhase.Generating);
            foreach (VisualLineElementGenerator g in generators) {
                g.StartGeneration(context);
            }
            elements = new List<VisualLineElement>();
            PerformVisualElementConstruction(generators);
            foreach (VisualLineElementGenerator g in generators) {
                g.FinishGeneration();
            }

            var globalTextRunProperties = context.GlobalTextRunProperties;
            foreach (var element in elements) {
                element.SetTextRunProperties(new VisualLineElementTextRunProperties(globalTextRunProperties));
            }
            this.Elements = elements.AsReadOnly();
            CalculateOffsets();
            phase = LifetimePhase.Transforming;
        }