예제 #1
0
    public static string GetBackIterators(Paragraph paragraph)
    {
      ParagraphIterator iter = new ParagraphIterator(paragraph.Elements);
      iter = iter.GetLastLeaf();
      string retString = "";
      while (iter != null)
      {
        retString += "[" + iter.Current.GetType().Name + ":]";
        if (iter.Current is Text)
          retString += ((Text)iter.Current).Content;

        iter = iter.GetPreviousLeaf();
      }
      return retString;
    }
        /// <summary>
        /// Returns the previous iterator to a leaf in the document object tree pointing.
        /// </summary>
        /// <returns>The previous leaf, null if none exists.</returns>
        internal ParagraphIterator GetPreviousLeaf()
        {
            //Move up to appropriate parent element
            ParagraphIterator parIterator = GetParentIterator();

            if (parIterator == null)
            {
                return(null);
            }

            int elementIndex         = LastIndex;
            ParagraphElements parEls = (ParagraphElements)parIterator._current;

            while (elementIndex == 0)
            {
                elementIndex = parIterator.LastIndex;
                parIterator  = parIterator.GetParentIterator();
                if (parIterator == null)
                {
                    break;
                }

                parEls = (ParagraphElements)parIterator._current;
            }
            if (parIterator == null)
            {
                return(null);
            }

            int newIndex = elementIndex - 1;

            if (newIndex < 0)
            {
                return(null);
            }

            List <int> indices = new List <int>(parIterator._positionIndices);//(Array_List)parIterator.positionIndices.Clone();

            indices.Add(newIndex);

            DocumentObject    obj      = GetNodeObject(parEls[newIndex]);
            ParagraphIterator iterator = new ParagraphIterator(_rootNode, obj, indices);

            return(iterator.SeekLastLeaf());
        }
예제 #3
0
        /// <summary>
        /// Returns the next iterator in the tree pointing to a leaf.
        /// </summary>
        /// <remarks>This function is intended to receive the renderable objects of a paragraph.
        /// Thus, empty ParagraphElement objects (which are collections) don't count as leafs.</remarks>
        internal ParagraphIterator GetNextLeaf()
        {
            //Move up to appropriate parent element
            ParagraphIterator parIterator = GetParentIterator();

            if (parIterator == null)
            {
                return(null);
            }

            int elementIndex         = this.LastIndex;
            ParagraphElements parEls = (ParagraphElements)parIterator.current;

            while (elementIndex == parEls.Count - 1)
            {
                elementIndex = parIterator.LastIndex;
                parIterator  = parIterator.GetParentIterator();
                if (parIterator == null)
                {
                    break;
                }

                parEls = (ParagraphElements)parIterator.current;
            }
            if (parIterator == null)
            {
                return(null);
            }
            int newIndex = elementIndex + 1;

            if (newIndex >= parEls.Count)
            {
                return(null);
            }

            ArrayList indices = (ArrayList)parIterator.positionIndices.Clone();

            indices.Add(newIndex);
            DocumentObject    obj      = GetNodeObject(parEls[newIndex]);
            ParagraphIterator iterator = new ParagraphIterator(this.rootNode, obj, indices);

            return(iterator.SeekFirstLeaf());
        }
예제 #4
0
    /// <summary>
    /// Initializes this instance for formatting.
    /// </summary>
    /// <param name="area">The area for formatting</param>
    /// <param name="previousFormatInfo">A previous format info.</param>
    /// <returns>False, if nothing of the paragraph will fit the area any more.</returns>
    private bool InitFormat(Area area, FormatInfo previousFormatInfo)
    {
      this.phase = Phase.Formatting;

      this.tabOffsets = new ArrayList();

      ParagraphFormatInfo prevParaFormatInfo = (ParagraphFormatInfo)previousFormatInfo;
      if (previousFormatInfo == null || prevParaFormatInfo.LineCount == 0)
      {
        ((ParagraphFormatInfo)this.renderInfo.FormatInfo).isStarting = true;
        ParagraphIterator parIt = new ParagraphIterator(this.paragraph.Elements);
        this.currentLeaf = parIt.GetFirstLeaf();
        this.isFirstLine = true;
      }
      else
      {
        this.currentLeaf = prevParaFormatInfo.GetLastLineInfo().endIter.GetNextLeaf();
        this.isFirstLine = false;
        ((ParagraphFormatInfo)this.renderInfo.FormatInfo).isStarting = false;
      }

      this.startLeaf = this.currentLeaf;
      this.currentVerticalInfo = CalcCurrentVerticalInfo();
      this.currentYPosition = area.Y + TopBorderOffset;
      this.formattingArea = area;
      Rectangle rect = this.formattingArea.GetFittingRect(this.currentYPosition, this.currentVerticalInfo.height);
      if (rect == null)
        return false;

      this.currentXPosition = rect.X + LeftIndent;
      if (this.isFirstLine)
        FormatListSymbol();

      return true;
    }
예제 #5
0
        /// <summary>
        /// Returns the previous iterator to a leaf in the document object tree pointing.
        /// </summary>
        /// <returns>The previous leaf, null if none exists.</returns>
        internal ParagraphIterator GetPreviousLeaf()
        {
            //Move up to appropriate parent element
              ParagraphIterator parIterator = GetParentIterator();
              if (parIterator == null)
            return null;

              int elementIndex = this.LastIndex;
              ParagraphElements parEls = (ParagraphElements)parIterator.current;
              while (elementIndex == 0)
              {
            elementIndex = parIterator.LastIndex;
            parIterator = parIterator.GetParentIterator();
            if (parIterator == null)
              break;

            parEls = (ParagraphElements)parIterator.current;
              }
              if (parIterator == null)
            return null;

              int newIndex = elementIndex - 1;
              if (newIndex < 0)
            return null;

              ArrayList indices = (ArrayList)parIterator.positionIndices.Clone();
              indices.Add(newIndex);

              DocumentObject obj = GetNodeObject(parEls[newIndex]);
              ParagraphIterator iterator = new ParagraphIterator(this.rootNode, obj, indices);
              return iterator.SeekLastLeaf();
        }
예제 #6
0
        /// <summary>
        /// Returns the next iterator in the tree pointing to a leaf.
        /// </summary>
        /// <remarks>This function is intended to receive the renderable objects of a paragraph.
        /// Thus, empty ParagraphElement objects (which are collections) don't count as leafs.</remarks>
        internal ParagraphIterator GetNextLeaf()
        {
            //Move up to appropriate parent element
            ParagraphIterator parIterator = GetParentIterator();
            if (parIterator == null)
                return null;

            int elementIndex = LastIndex;
            ParagraphElements parEls = (ParagraphElements)parIterator._current;
            while (elementIndex == parEls.Count - 1)
            {
                elementIndex = parIterator.LastIndex;
                parIterator = parIterator.GetParentIterator();
                if (parIterator == null)
                    break;

                parEls = (ParagraphElements)parIterator._current;
            }
            if (parIterator == null)
                return null;
            int newIndex = elementIndex + 1;
            if (newIndex >= parEls.Count)
                return null;

            List<int> indices = new List<int>(parIterator._positionIndices); //(Array_List)parIterator.positionIndices.Clone();
            indices.Add(newIndex);
            DocumentObject obj = GetNodeObject(parEls[newIndex]);
            ParagraphIterator iterator = new ParagraphIterator(_rootNode, obj, indices);
            return iterator.SeekFirstLeaf();
        }
예제 #7
0
        FormatResult FormatLineBreak()
        {
            if (this.phase != Phase.Rendering)
            this.currentLeaf = this.currentLeaf.GetNextLeaf();

              this.savedWordWidth = 0;
              return FormatResult.NewLine;
        }
예제 #8
0
        /// <summary>
        /// Initializes this instance for formatting.
        /// </summary>
        /// <param name="area">The area for formatting</param>
        /// <param name="previousFormatInfo">A previous format info.</param>
        /// <returns>False, if nothing of the paragraph will fit the area any more.</returns>
        private bool InitFormat(Area area, FormatInfo previousFormatInfo)
        {
            _phase = Phase.Formatting;

            _tabOffsets = new List<TabOffset>();

            ParagraphFormatInfo prevParaFormatInfo = (ParagraphFormatInfo)previousFormatInfo;
            if (previousFormatInfo == null || prevParaFormatInfo.LineCount == 0)
            {
                ((ParagraphFormatInfo)_renderInfo.FormatInfo)._isStarting = true;
                ParagraphIterator parIt = new ParagraphIterator(_paragraph.Elements);
                _currentLeaf = parIt.GetFirstLeaf();
                _isFirstLine = true;
            }
            else
            {
                _currentLeaf = prevParaFormatInfo.GetLastLineInfo().EndIter.GetNextLeaf();
                _isFirstLine = false;
                ((ParagraphFormatInfo)_renderInfo.FormatInfo)._isStarting = false;
            }

            _startLeaf = _currentLeaf;
            _currentVerticalInfo = CalcCurrentVerticalInfo();
            _currentYPosition = area.Y + TopBorderOffset;
            _formattingArea = area;
            Rectangle rect = _formattingArea.GetFittingRect(_currentYPosition, _currentVerticalInfo.Height);
            if (rect == null)
                return false;

            _currentXPosition = rect.X + LeftIndent;
            if (_isFirstLine)
                FormatListSymbol();

            return true;
        }
예제 #9
0
 void SaveBeforeProbing(out ParagraphIterator paragraphIter, out int blankCount, out XUnit wordsWidth, out XUnit xPosition, out XUnit lineWidth, out XUnit blankWidth)
 {
   paragraphIter = this.currentLeaf;
   blankCount = this.currentBlankCount;
   xPosition = this.currentXPosition;
   lineWidth = this.currentLineWidth;
   wordsWidth = this.currentWordsWidth;
   blankWidth = this.savedBlankWidth;
 }
예제 #10
0
        /// <summary>
        /// Renders a single line.
        /// </summary>
        /// <param name="lineInfo"></param>
        void RenderLine(LineInfo lineInfo)
        {
            this.currentVerticalInfo = lineInfo.vertical;
              this.currentLeaf = lineInfo.startIter;
              this.startLeaf = lineInfo.startIter;
              this.endLeaf = lineInfo.endIter;
              this.currentBlankCount = lineInfo.blankCount;
              this.currentLineWidth = lineInfo.lineWidth;
              this.currentWordsWidth = lineInfo.wordsWidth;
              this.currentXPosition = this.StartXPosition;
              this.tabOffsets = lineInfo.tabOffsets;
              this.lastTabPassed = lineInfo.lastTab == null;
              this.lastTab = lineInfo.lastTab;

              this.tabIdx = 0;

              bool ready = this.currentLeaf == null;
              if (this.isFirstLine)
            RenderListSymbol();

              while (!ready)
              {
            if (this.currentLeaf.Current == lineInfo.endIter.Current)
              ready = true;

            if (this.currentLeaf.Current == lineInfo.lastTab)
              this.lastTabPassed = true;
            RenderElement(this.currentLeaf.Current);
            this.currentLeaf = this.currentLeaf.GetNextLeaf();
              }
              this.currentYPosition += lineInfo.vertical.height;
              this.isFirstLine = false;
        }
예제 #11
0
        void ReMeasureLine(ref LineInfo lineInfo)
        {
            //--- Save ---------------------------------
              ParagraphIterator iter;
              int blankCount;
              XUnit xPosition;
              XUnit lineWidth;
              XUnit wordsWidth;
              XUnit blankWidth;
              SaveBeforeProbing(out iter, out blankCount, out wordsWidth, out xPosition, out lineWidth, out blankWidth);
              bool origLastTabPassed = this.lastTabPassed;
              //------------------------------------------
              this.currentLeaf = lineInfo.startIter;
              this.endLeaf = lineInfo.endIter;
              this.formattingArea = this.renderInfo.LayoutInfo.ContentArea;
              this.tabOffsets = new ArrayList();
              this.currentLineWidth = 0;
              this.currentWordsWidth = 0;

              Rectangle fittingRect = this.formattingArea.GetFittingRect(this.currentYPosition, this.currentVerticalInfo.height);
              if (fittingRect == null)
            GetType();
              if (fittingRect != null)
              {
            this.currentXPosition = fittingRect.X + this.LeftIndent;
            FormatListSymbol();
            bool goOn = true;
            while (goOn && this.currentLeaf != null)
            {
              if (this.currentLeaf.Current == lineInfo.lastTab)
            this.lastTabPassed = true;

              FormatElement(this.currentLeaf.Current);

              goOn = this.currentLeaf != null && this.currentLeaf.Current != this.endLeaf.Current;
              if (goOn)
            this.currentLeaf = this.currentLeaf.GetNextLeaf();
            }
            lineInfo.lineWidth = this.currentLineWidth;
            lineInfo.wordsWidth = this.currentWordsWidth;
            lineInfo.blankCount = this.currentBlankCount;
            lineInfo.tabOffsets = this.tabOffsets;
            lineInfo.reMeasureLine = false;
            this.lastTabPassed = origLastTabPassed;
              }
              RestoreAfterProbing(iter, blankCount, wordsWidth, xPosition, lineWidth, blankWidth);
        }
예제 #12
0
        /// <summary>
        /// Probes the paragraph after a tab.
        /// Caution: This Function resets the word count and line width before doing its work.
        /// </summary>
        /// <returns>True if the tab causes a linebreak.</returns>
        bool ProbeAfterTab()
        {
            this.currentLineWidth = 0;
              this.currentBlankCount = 0;
              //Extra for auto tab after list symbol

              //TODO: KLPO4KLPO: Check if this conditional statement is still required
              if (this.currentLeaf != null && IsTab(this.currentLeaf.Current))
            this.currentLeaf = this.currentLeaf.GetNextLeaf();

              bool wordAppeared = false;
              while (this.currentLeaf != null && !IsLineBreak(this.currentLeaf.Current) && !IsTab(this.currentLeaf.Current))
              {
            FormatResult result = FormatElement(this.currentLeaf.Current);
            if (result != FormatResult.Continue)
              break;

            wordAppeared = wordAppeared || IsWordLikeElement(this.currentLeaf.Current);
            this.currentLeaf = this.currentLeaf.GetNextLeaf();
              }
              return this.currentLeaf != null && !IsLineBreak(this.currentLeaf.Current) &&
            !IsTab(this.currentLeaf.Current) && !wordAppeared;
        }
예제 #13
0
        /// <summary>
        /// Probes the paragraph elements after a right aligned tab stop and returns the vertical text position to start at.
        /// </summary>
        /// <param name="tabStopPosition">Position of the tab to probe.</param>
        /// <param name="notFitting">Out parameter determining whether the tab causes a line break.</param>
        /// <returns>The new x-position to restart behind the tab.</returns>
        XUnit ProbeAfterDecimalAlignedTab(XUnit tabStopPosition, out bool notFitting)
        {
            notFitting = false;
              ParagraphIterator savedLeaf = this.currentLeaf;

              //Extra for auto tab after list symbol
              if (IsTab(this.currentLeaf.Current))
            this.currentLeaf = this.currentLeaf.GetNextLeaf();
              if (this.currentLeaf == null)
              {
            this.currentLeaf = savedLeaf;
            return this.currentXPosition + tabStopPosition;
              }
              VerticalLineInfo newVerticalInfo = CalcCurrentVerticalInfo();
              Rectangle fittingRect = this.formattingArea.GetFittingRect(this.currentYPosition, newVerticalInfo.height);
              if (fittingRect == null)
              {
            notFitting = true;
            this.currentLeaf = savedLeaf;
            return this.currentXPosition;
              }

              if (IsPlainText(this.currentLeaf.Current))
              {
            Text text = (Text)this.currentLeaf.Current;
            string word = text.Content;
            int lastIndex = text.Content.LastIndexOfAny(new char[] { ',', '.' });
            if (lastIndex > 0)
              word = word.Substring(0, lastIndex);

            XUnit wordLength = MeasureString(word);
            notFitting = this.currentXPosition + wordLength >= formattingArea.X + formattingArea.Width + Tolerance;
            if (!notFitting)
              return this.formattingArea.X + tabStopPosition - wordLength;

            else
              return this.currentXPosition;
              }
              this.currentLeaf = savedLeaf;
              return ProbeAfterRightAlignedTab(tabStopPosition, out notFitting);
        }
예제 #14
0
 void HandleNonFittingLine()
 {
     if (this.currentLeaf != null)
       {
     if (this.savedWordWidth > 0)
     {
       this.currentWordsWidth = this.savedWordWidth;
       this.currentLineWidth = this.savedWordWidth;
     }
     this.currentLeaf = this.currentLeaf.GetNextLeaf();
     this.currentYPosition += this.currentVerticalInfo.height;
     this.currentVerticalInfo = new VerticalLineInfo();
       }
 }
예제 #15
0
        FormatResult FormatSoftHyphen()
        {
            if (this.currentLeaf.Current == this.startLeaf.Current)
            return FormatResult.Continue;

              ParagraphIterator nextIter = this.currentLeaf.GetNextLeaf();
              ParagraphIterator prevIter = this.currentLeaf.GetPreviousLeaf();
              if (!IsWordLikeElement(prevIter.Current) || !IsWordLikeElement(nextIter.Current))
            return FormatResult.Continue;

              //--- Save ---------------------------------
              ParagraphIterator iter;
              int blankCount;
              XUnit xPosition;
              XUnit lineWidth;
              XUnit wordsWidth;
              XUnit blankWidth;
              SaveBeforeProbing(out iter, out blankCount, out wordsWidth, out xPosition, out lineWidth, out blankWidth);
              //------------------------------------------
              this.currentLeaf = nextIter;
              FormatResult result = FormatElement(nextIter.Current);

              //--- Restore ------------------------------
              RestoreAfterProbing(iter, blankCount, wordsWidth, xPosition, lineWidth, blankWidth);
              //------------------------------------------
              if (result == FormatResult.Continue)
            return FormatResult.Continue;

              RestoreAfterProbing(iter, blankCount, wordsWidth, xPosition, lineWidth, blankWidth);
              Rectangle fittingRect = this.formattingArea.GetFittingRect(this.currentYPosition, this.currentVerticalInfo.height);

              XUnit hyphenWidth = MeasureString("-");
              if (xPosition + hyphenWidth <= fittingRect.X + fittingRect.Width + Tolerance
              // If one word fits, but not the hyphen, the formatting must continue with the next leaf
              || prevIter.Current == this.startLeaf.Current)
              {
            // For Tabs in justified context
            if (!IgnoreHorizontalGrowth)
            {
              this.currentWordsWidth += hyphenWidth;
              this.currentLineWidth += hyphenWidth;
            }
            this.currentLeaf = nextIter;
            return FormatResult.NewLine;
              }
              else
              {
            this.currentWordsWidth -= this.savedWordWidth;
            this.currentLineWidth -= this.savedWordWidth;
            this.currentLineWidth -= GetPreviousBlankWidth(prevIter);
            this.currentLeaf = prevIter;
            return FormatResult.NewLine;
              }
        }
예제 #16
0
    XUnit GetPreviousBlankWidth(ParagraphIterator beforeIter)
    {
      XUnit width = 0;
      ParagraphIterator savedIter = this.currentLeaf;
      this.currentLeaf = beforeIter.GetPreviousLeaf();
      while (this.currentLeaf != null)
      {
        if (this.currentLeaf.Current is BookmarkField)
          this.currentLeaf = this.currentLeaf.GetPreviousLeaf();
        else if (IsBlank(this.currentLeaf.Current))
        {
          if (!IgnoreBlank())
            width = CurrentWordDistance;

          break;
        }
        else
          break;
      }
      this.currentLeaf = savedIter;
      return width;
    }
예제 #17
0
    string GetOutlineTitle()
    {
      ParagraphIterator iter = new ParagraphIterator(this.paragraph.Elements);
      iter = iter.GetFirstLeaf();

      bool ignoreBlank = true;
      string title = "";
      while (iter != null)
      {
        DocumentObject current = iter.Current;
        if (!ignoreBlank && (IsBlank(current) || IsTab(current) || IsLineBreak(current)))
        {
          title += " ";
          ignoreBlank = true;
        }
        else if (current is Text)
        {
          title += ((Text)current).Content;
          ignoreBlank = false;
        }
        else if (IsRenderedField(current))
        {
          title += GetFieldValue(current);
          ignoreBlank = false;
        }
        else if (IsSymbol(current))
        {
          title += GetSymbol((Character)current);
          ignoreBlank = false;
        }

        if (title.Length > 64)
          break;
        iter = iter.GetNextLeaf();
      }
      return title;
    }
예제 #18
0
        /// <summary>
        /// Starts a new line by resetting measuring values.
        /// Do not call before the first first line is formatted!
        /// </summary>
        /// <returns>True, if the new line may fit the formatting area.</returns>
        bool StartNewLine()
        {
            this.tabOffsets = new ArrayList();
              this.lastTab = null;
              this.lastTabPosition = 0;
              this.currentYPosition += this.currentVerticalInfo.height;
            #if true
              Rectangle rect = this.formattingArea.GetFittingRect(currentYPosition, this.currentVerticalInfo.height + BottomBorderOffset);
              if (rect == null)
            return false;

              this.isFirstLine = false;
              this.currentXPosition = StartXPosition; // depends on "currentVerticalInfo"
              this.currentVerticalInfo = new VerticalLineInfo();
              this.currentVerticalInfo = CalcCurrentVerticalInfo();
            #else
              if (this.formattingArea.GetFittingRect(currentYPosition, this.currentVerticalInfo.height + BottomBorderOffset) == null)
            return false;

              this.currentVerticalInfo = new VerticalLineInfo();
              this.currentVerticalInfo = CalcCurrentVerticalInfo();
              this.isFirstLine = false;
              this.currentXPosition = this.StartXPosition;
            #endif
              this.startLeaf = this.currentLeaf;
              this.currentBlankCount = 0;
              this.currentWordsWidth = 0;
              this.currentLineWidth = 0;
              return true;
        }
예제 #19
0
 void RestoreAfterProbing(ParagraphIterator paragraphIter, int blankCount, XUnit wordsWidth, XUnit xPosition, XUnit lineWidth, XUnit blankWidth)
 {
   this.currentLeaf = paragraphIter;
   this.currentBlankCount = blankCount;
   this.currentXPosition = xPosition;
   this.currentLineWidth = lineWidth;
   this.currentWordsWidth = wordsWidth;
   this.savedBlankWidth = blankWidth;
 }
예제 #20
0
        /// <summary>
        /// Formats the paragraph by performing line breaks etc.
        /// </summary>
        /// <param name="area">The area in which to render.</param>
        /// <param name="previousFormatInfo">The format info that was obtained on formatting the same paragraph on a previous area.</param>
        internal override void Format(Area area, FormatInfo previousFormatInfo)
        {
            ParagraphFormatInfo formatInfo = ((ParagraphFormatInfo)this.renderInfo.FormatInfo);
              if (!InitFormat(area, previousFormatInfo))
              {
            formatInfo.isStarting = false;
            return;
              }
              formatInfo.isEnding = true;

              FormatResult lastResult = FormatResult.Continue;
              while (this.currentLeaf != null)
              {
            FormatResult result = FormatElement(this.currentLeaf.Current);
            switch (result)
            {
              case FormatResult.Ignore:
            this.currentLeaf = this.currentLeaf.GetNextLeaf();
            break;

              case FormatResult.Continue:
            lastResult = result;
            this.currentLeaf = this.currentLeaf.GetNextLeaf();
            break;

              case FormatResult.NewLine:
            lastResult = result;
            StoreLineInformation();
            if (!StartNewLine())
            {
              result = FormatResult.NewArea;
              formatInfo.isEnding = false;
            }
            break;
            }
            if (result == FormatResult.NewArea)
            {
              lastResult = result;
              formatInfo.isEnding = false;
              break;
            }
              }
              if (formatInfo.IsEnding && lastResult != FormatResult.NewLine)
            StoreLineInformation();

              formatInfo.imageRenderInfos = this.imageRenderInfos;
              FinishLayoutInfo();
        }