/// <summary>
        /// Add a character formatting to a range in this paragraph.
        /// To specify the whole paragraph as the range, set begin = end = -1.
        /// Format that is added latter will override the former, if their
        /// range overlays each other.
        /// </summary>
        /// <param name="begin">Beginning of the range</param>
        /// <param name="end">End of the range</param>
        public RtfCharFormat addCharFormat(int begin, int end)
        {
            RtfCharFormat fmt = new RtfCharFormat(begin, end, _text.Length);

            _charFormats.Add(fmt);
            return(fmt);
        }
Пример #2
0
 internal void copyFrom(RtfCharFormat src)
 {
     if (src == null)
     {
         return;
     }
     _begin = src._begin;
     _end   = src._end;
     if (_font == null && src._font != null)
     {
         _font = new FontDescriptor(src._font.Value);
     }
     if (_ansiFont == null && src._ansiFont != null)
     {
         _ansiFont = new FontDescriptor(src._ansiFont.Value);
     }
     if (_fontSize < 0 && src._fontSize >= 0)
     {
         _fontSize = src._fontSize;
     }
     if (_fontStyle.IsEmpty && !src._fontStyle.IsEmpty)
     {
         _fontStyle = new FontStyle(src._fontStyle);
     }
     if (_bgColor == null && src._bgColor != null)
     {
         _bgColor = new ColorDescriptor(src._bgColor.Value);
     }
     if (_fgColor == null && src._fgColor != null)
     {
         _fgColor = new ColorDescriptor(src._fgColor.Value);
     }
 }
 /// <summary>
 /// Internal use only.
 /// Constructor specifying allowed content blocks to be contained.
 /// </summary>
 /// <param name="allowParagraph">Whether an RtfParagraph is allowed.</param>
 /// <param name="allowFootnote">Whether an RtfFootnote is allowed in contained RtfParagraph.</param>
 /// <param name="allowControlWord">Whether an field control word is allowed in contained
 /// RtfParagraph.</param>
 /// <param name="allowImage">Whether RtfImage is allowed.</param>
 /// <param name="allowTable">Whether RtfTable is allowed.</param>
 internal RtfBlockList(bool allowParagraph, bool allowFootnote, bool allowControlWord,
                       bool allowImage, bool allowTable)
 {
     _blocks            = new List <RtfBlock>();
     _allowParagraph    = allowParagraph;
     _allowFootnote     = allowFootnote;
     _allowControlWord  = allowControlWord;
     _allowImage        = allowImage;
     _allowTable        = allowTable;
     _defaultCharFormat = null;
 }
 public RtfParagraph(bool allowFootnote, bool allowControlWord)
 {
     _text              = new StringBuilder();
     _linespacing       = -1;
     _margins           = new Margins();
     _align             = Align.Left; //Changed default to .Left as .None was spreading text accross page.
     _charFormats       = new List <RtfCharFormat>();
     _allowFootnote     = allowFootnote;
     _allowControlWord  = allowControlWord;
     _footnotes         = new List <RtfFootnote>();
     _controlWords      = new List <RtfFieldControlWord>();
     _blockHead         = @"{\pard";
     _blockTail         = @"\par}";
     _startNewPage      = false;
     _firstLineIndent   = 0;
     _defaultCharFormat = null;
 }
        protected LinkedList <Token> buildTokenList()
        {
            int   count;
            Token token;
            LinkedList <Token>     tokList = new LinkedList <Token>();
            LinkedListNode <Token> node;
            List <DisjointRange>   dranges = new List <DisjointRange>();

            #region Build head[] and tail[] from char format range for later use.
            // --------------------------------------------------
            // Transform possibly overlapped character format ranges into
            // disjoint ranges.
            // --------------------------------------------------
            for (int i = 0; i < _charFormats.Count; i++)
            {
                RtfCharFormat fmt   = _charFormats[i];
                DisjointRange range = null;
                if (fmt.Begin == -1 && fmt.End == -1)
                {
                    range        = new DisjointRange();
                    range.head   = 0;
                    range.tail   = _text.Length - 1;
                    range.format = fmt;
                }
                else if (fmt.Begin <= fmt.End)
                {
                    range        = new DisjointRange();
                    range.head   = fmt.Begin;
                    range.tail   = fmt.End;
                    range.format = fmt;
                }
                else
                {
                    continue;
                }
                if (range.tail >= _text.Length)
                {
                    range.tail = _text.Length - 1;
                    if (range.head > range.tail)
                    {
                        continue;
                    }
                }
                // make the ranges disjoint from each other.
                List <DisjointRange> delList       = new List <DisjointRange>();
                List <DisjointRange> addList       = new List <DisjointRange>();
                List <DisjointRange> addAnchorList = new List <DisjointRange>();
                for (int j = 0; j < dranges.Count; j++)
                {
                    DisjointRange r = dranges[j];
                    if (range.head <= r.head && range.tail >= r.tail)
                    {
                        // former range is totally covered by the later
                        //       |--------| r
                        //   |-----------------| range
                        delList.Add(r);
                    }
                    else if (range.head <= r.head && range.tail >= r.head && range.tail < r.tail)
                    {
                        // former range is partially covered
                        //          |------------------| r
                        //     |-----------------| range
                        r.head = range.tail + 1;
                    }
                    else if (range.head > r.head && range.head <= r.tail && range.tail >= r.tail)
                    {
                        // former range is partially covered
                        //     |------------------| r
                        //          |-----------------| range
                        r.tail = range.head - 1;
                    }
                    else if (range.head > r.head && range.tail < r.tail)
                    {
                        // later range is totally covered by the former
                        //   |----------------------| r
                        //        |---------| range
                        DisjointRange newRange = new DisjointRange();
                        newRange.head   = range.tail + 1;
                        newRange.tail   = r.tail;
                        newRange.format = r.format;
                        r.tail          = range.head - 1;
                        addList.Add(newRange);
                        addAnchorList.Add(r);
                    }
                }
                dranges.Add(range);
                for (int j = 0; j < delList.Count; j++)
                {
                    dranges.Remove(delList[j]);
                }
                for (int j = 0; j < addList.Count; j++)
                {
                    int index = dranges.IndexOf(addAnchorList[j]);
                    if (index < 0)
                    {
                        continue;
                    }
                    dranges.Insert(index, addList[j]);
                }
            }
            #endregion
            token           = new Token();
            token.text      = _text.ToString();
            token.isControl = false;
            tokList.AddLast(token);
            #region Build token list from head[] and tail[].
            // --------------------------------------------------
            // Build token list from head[] and tail[].
            // --------------------------------------------------
            for (int i = 0; i < dranges.Count; i++)
            {
                DisjointRange r = dranges[i];
                count = 0;
                // process head[i]
                if (r.head == 0)
                {
                    Token newTok = new Token();
                    newTok.isControl = true;
                    newTok.text      = r.format.renderHead();
                    tokList.AddFirst(newTok);
                }
                else
                {
                    node = tokList.First;
                    while (node != null)
                    {
                        Token tok = node.Value;

                        if (!tok.isControl)
                        {
                            count += tok.text.Length;
                            if (count == r.head)
                            {
                                Token newTok = new Token();
                                newTok.isControl = true;
                                newTok.text      = r.format.renderHead();
                                while (node.Next != null && node.Next.Value.isControl)
                                {
                                    node = node.Next;
                                }
                                tokList.AddAfter(node, newTok);
                                break;
                            }
                            else if (count > r.head)
                            {
                                LinkedListNode <Token> newNode;
                                Token newTok1 = new Token();
                                newTok1.isControl = false;
                                newTok1.text      = tok.text.Substring(0, tok.text.Length - (count - r.head));
                                newNode           = tokList.AddAfter(node, newTok1);
                                Token newTok2 = new Token();
                                newTok2.isControl = true;
                                newTok2.text      = r.format.renderHead();
                                newNode           = tokList.AddAfter(newNode, newTok2);
                                Token newTok3 = new Token();
                                newTok3.isControl = false;
                                newTok3.text      = tok.text.Substring(tok.text.Length - (count - r.head));
                                newNode           = tokList.AddAfter(newNode, newTok3);
                                tokList.Remove(node);
                                break;
                            }
                        }
                        node = node.Next;
                    }
                }
                // process tail[i]
                count = 0;
                node  = tokList.First;
                while (node != null)
                {
                    Token tok = node.Value;

                    if (!tok.isControl)
                    {
                        count += tok.text.Length;
                        if (count - 1 == r.tail)
                        {
                            Token newTok = new Token();
                            newTok.isControl = true;
                            newTok.text      = r.format.renderTail();
                            tokList.AddAfter(node, newTok);
                            break;
                        }
                        else if (count - 1 > r.tail)
                        {
                            LinkedListNode <Token> newNode;
                            Token newTok1 = new Token();
                            newTok1.isControl = false;
                            newTok1.text      = tok.text.Substring(0, tok.text.Length - (count - r.tail) + 1);
                            newNode           = tokList.AddAfter(node, newTok1);
                            Token newTok2 = new Token();
                            newTok2.isControl = true;
                            newTok2.text      = r.format.renderTail();
                            newNode           = tokList.AddAfter(newNode, newTok2);
                            Token newTok3 = new Token();
                            newTok3.isControl = false;
                            newTok3.text      = tok.text.Substring(tok.text.Length - (count - r.tail) + 1);
                            newNode           = tokList.AddAfter(newNode, newTok3);
                            tokList.Remove(node);
                            break;
                        }
                    }
                    node = node.Next;
                }
            } // end for each char format
            #endregion
            #region Insert footnote into token list.
            // --------------------------------------------------
            // Insert footnote into token list.
            // --------------------------------------------------
            for (int i = 0; i < _footnotes.Count; i++)
            {
                int pos = _footnotes[i].Position;
                if (pos >= _text.Length)
                {
                    continue;
                }

                count = 0;
                node  = tokList.First;
                while (node != null)
                {
                    Token tok = node.Value;

                    if (!tok.isControl)
                    {
                        count += tok.text.Length;
                        if (count - 1 == pos)
                        {
                            Token newTok = new Token();
                            newTok.isControl = true;
                            newTok.text      = _footnotes[i].render();
                            tokList.AddAfter(node, newTok);
                            break;
                        }
                        else if (count - 1 > pos)
                        {
                            LinkedListNode <Token> newNode;
                            Token newTok1 = new Token();
                            newTok1.isControl = false;
                            newTok1.text      = tok.text.Substring(0, tok.text.Length - (count - pos) + 1);
                            newNode           = tokList.AddAfter(node, newTok1);
                            Token newTok2 = new Token();
                            newTok2.isControl = true;
                            newTok2.text      = _footnotes[i].render();
                            newNode           = tokList.AddAfter(newNode, newTok2);
                            Token newTok3 = new Token();
                            newTok3.isControl = false;
                            newTok3.text      = tok.text.Substring(tok.text.Length - (count - pos) + 1);
                            newNode           = tokList.AddAfter(newNode, newTok3);
                            tokList.Remove(node);
                            break;
                        }
                    }
                    node = node.Next;
                }
            }
            #endregion
            #region Insert control words into token list.
            // --------------------------------------------------
            // Insert control words into token list.
            // --------------------------------------------------
            for (int i = 0; i < _controlWords.Count; i++)
            {
                int pos = _controlWords[i].Position;
                if (pos >= _text.Length)
                {
                    continue;
                }

                count = 0;
                node  = tokList.First;
                while (node != null)
                {
                    Token tok = node.Value;

                    if (!tok.isControl)
                    {
                        count += tok.text.Length;
                        if (count - 1 == pos)
                        {
                            Token newTok = new Token();
                            newTok.isControl = true;
                            newTok.text      = _controlWords[i].render();
                            tokList.AddAfter(node, newTok);
                            break;
                        }
                        else if (count - 1 > pos)
                        {
                            LinkedListNode <Token> newNode;
                            Token newTok1 = new Token();
                            newTok1.isControl = false;
                            newTok1.text      = tok.text.Substring(0, tok.text.Length - (count - pos) + 1);
                            newNode           = tokList.AddAfter(node, newTok1);
                            Token newTok2 = new Token();
                            newTok2.isControl = true;
                            newTok2.text      = _controlWords[i].render();
                            newNode           = tokList.AddAfter(newNode, newTok2);
                            Token newTok3 = new Token();
                            newTok3.isControl = false;
                            newTok3.text      = tok.text.Substring(tok.text.Length - (count - pos) + 1);
                            newNode           = tokList.AddAfter(newNode, newTok3);
                            tokList.Remove(node);
                            break;
                        }
                    }
                    node = node.Next;
                }
            }
            #endregion

            return(tokList);
        }