// Token: 0x0600329A RID: 12954 RVA: 0x000E3B2C File Offset: 0x000E1D2C
        internal void Push()
        {
            FormatState formatState = this.Top();
            FormatState value       = (formatState != null) ? new FormatState(formatState) : new FormatState();

            this.Add(value);
        }
Esempio n. 2
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        internal void Push()
        {
            FormatState previousFormatState = Top();
            FormatState formatState;

            formatState = previousFormatState != null ? new FormatState(previousFormatState) : new FormatState();

            Add(formatState);
        }
Esempio n. 3
0
 // Token: 0x060032DB RID: 13019 RVA: 0x000E5194 File Offset: 0x000E3394
 internal FormatState(FormatState formatState)
 {
     this.Bold              = formatState.Bold;
     this.Italic            = formatState.Italic;
     this.Engrave           = formatState.Engrave;
     this.Shadow            = formatState.Shadow;
     this.SCaps             = formatState.SCaps;
     this.Outline           = formatState.Outline;
     this.Super             = formatState.Super;
     this.Sub               = formatState.Sub;
     this.SuperOffset       = formatState.SuperOffset;
     this.FontSize          = formatState.FontSize;
     this.Font              = formatState.Font;
     this.CodePage          = formatState.CodePage;
     this.CF                = formatState.CF;
     this.CB                = formatState.CB;
     this.DirChar           = formatState.DirChar;
     this.UL                = formatState.UL;
     this.Strike            = formatState.Strike;
     this.Expand            = formatState.Expand;
     this.Lang              = formatState.Lang;
     this.LangFE            = formatState.LangFE;
     this.LangCur           = formatState.LangCur;
     this.FontSlot          = formatState.FontSlot;
     this.SB                = formatState.SB;
     this.SA                = formatState.SA;
     this.FI                = formatState.FI;
     this.RI                = formatState.RI;
     this.LI                = formatState.LI;
     this.SL                = formatState.SL;
     this.SLMult            = formatState.SLMult;
     this.HAlign            = formatState.HAlign;
     this.ILVL              = formatState.ILVL;
     this.ITAP              = formatState.ITAP;
     this.ILS               = formatState.ILS;
     this.DirPara           = formatState.DirPara;
     this.CFPara            = formatState.CFPara;
     this.CBPara            = formatState.CBPara;
     this.ParaShading       = formatState.ParaShading;
     this.Marker            = formatState.Marker;
     this.IsContinue        = formatState.IsContinue;
     this.StartIndex        = formatState.StartIndex;
     this.StartIndexDefault = formatState.StartIndexDefault;
     this.IsInTable         = formatState.IsInTable;
     this._pb               = (formatState.HasParaBorder ? new ParaBorder(formatState.ParaBorder) : null);
     this.RowFormat         = formatState._rowFormat;
     this.RtfDestination    = formatState.RtfDestination;
     this.IsHidden          = formatState.IsHidden;
     this._stateSkip        = formatState.UnicodeSkip;
 }
        internal void HandlePara(RtfToken token, FormatState formatState)
        {
            // Ignore \par in other destinations
            if (!formatState.IsContentDestination || formatState.IsHidden)
            {
                return;
            }

            // Arrival of paragraph tag allows us to rationalize structure information.
            // Various tags have told us things about this paragraph:
            //        \INTBL:        Paragraph is inside a table cell.
            //        \ITAP{N}:    Nesting level for table.  Note that I may not have yet
            //                    seen any tags that start the nested table.
            //        \LS{N}:        Listtable override index.  Any value indicates this paragraph
            //                    is in a list.
            //        \ILVL:        Nesting level for list.

            // If we're in a throw-away destination, just return.
            HandleParagraphFromText(formatState);

            // Make sure proper number of tables are open to reflect this paragraphs nest level
            HandleTableNesting(formatState);

            // Now handle lists, which always behave as if they are inside tables.
            HandleListNesting(formatState);
        }
        private void ProcessRtfDestination(FormatState fsCur)
        {
            DocumentNodeArray dna = _converterState.DocumentNodeArray;
            int nAt;

            switch (fsCur.RtfDestination)
            {
                case RtfDestination.DestField:
                    nAt = dna.FindUnmatched(DocumentNodeType.dnFieldBegin);
                    if (nAt >= 0)
                    {
                        DocumentNode dnEnd = new DocumentNode(DocumentNodeType.dnFieldEnd);
                        dnEnd.FormatState = new FormatState(fsCur);
                        dnEnd.IsPending = false;
                        dna.Push(dnEnd);
                        dna.EntryAt(nAt).IsMatched = true;
                        ProcessField();
                    }
                    break;
                case RtfDestination.DestFieldInstruction:
                case RtfDestination.DestFieldPrivate:
                case RtfDestination.DestFieldResult:
                    nAt = dna.FindUnmatched(DocumentNodeType.dnFieldBegin);
                    if (nAt >= 0)
                    {
                        DocumentNode dnEnd = new DocumentNode(DocumentNodeType.dnFieldEnd);
                        dnEnd.FormatState = new FormatState(fsCur);
                        dnEnd.IsPending = false;
                        dna.Push(dnEnd);
                        dna.EntryAt(nAt).IsMatched = true;
                    }
                    break;

                // The DestShape destination is only to distinguish the case of leaving a shaperesult destination
                // when shapes were nested.  No processing is actually necessary here.
                case RtfDestination.DestShape:
                    break;

                case RtfDestination.DestShapeResult:
                    ProcessShapeResult();
                    break;

                case RtfDestination.DestListText:
                    ProcessListText();
                    break;

                case RtfDestination.DestListLevel:
                    {
                        ListTableEntry listTableEntry = _converterState.ListTable.CurrentEntry;
                        if (listTableEntry != null)
                        {
                            ListLevel listLevel = listTableEntry.Levels.CurrentEntry;
                            listLevel.FormatState = new FormatState(fsCur);
                        }
                    }
                    break;

                case RtfDestination.DestListOverride:
                    break;

                case RtfDestination.DestList:
                    break;

                case RtfDestination.DestFontName:
                    FontTableEntry entry = _converterState.FontTable.CurrentEntry;
                    if (entry != null)
                    {
                        entry.IsNameSealed = true;
                        entry.IsPending = false;
                    }
                    break;

                case RtfDestination.DestFontTable:
                    _converterState.FontTable.MapFonts();
                    break;
            }
        }
        internal void ProcessImage(FormatState formatState)
        {
            string contentType;
            string imagePartUriString;

            switch (formatState.ImageFormat)
            {
                case RtfImageFormat.Wmf:
                case RtfImageFormat.Png:
                    contentType = "image/png";
                    break;

                case RtfImageFormat.Jpeg:
                    contentType = "image/jpeg";
                    break;

                default:
                    contentType = string.Empty;
                    break;
            }

            bool skipImage = (formatState.ImageScaleWidth < 0) || (formatState.ImageScaleHeight < 0);

            if (_wpfPayload != null && contentType != string.Empty && !skipImage)
            {
                // Get image part URI string and image binary steam to write Rtf image data
                // into the container of WpfPayload
                Stream imageStream = _wpfPayload.CreateImageStream(_imageCount, contentType, out imagePartUriString);

                using (imageStream)
                {
                    if (formatState.ImageFormat != RtfImageFormat.Wmf)
                    {
                        // Write the image binary data on the container from Rtf image data
                        _lexer.WriteImageData(imageStream, formatState.IsImageDataBinary);
                    }
                    else
                    {
                        // Read the windows metafile from the rtf content and then convert it
                        // to bitmap data then save it as PNG on the container image part
                        MemoryStream metafileStream = new MemoryStream(); ;

                        using (metafileStream)
                        {
                            // Get Windows Metafile from rtf content
                            _lexer.WriteImageData(metafileStream, formatState.IsImageDataBinary);

                            metafileStream.Position = 0;

                            SystemDrawingHelper.SaveMetafileToImageStream(metafileStream, imageStream);
                        }
                    }
                }

                // Increase the image count to generate the image source name
                _imageCount++;

                formatState.ImageSource = imagePartUriString;

                // Create the image document node
                DocumentNode dnImage = new DocumentNode(DocumentNodeType.dnImage);

                dnImage.FormatState = formatState;

                StringBuilder imageStringBuilder = new StringBuilder();

                // Add the xaml image element
                imageStringBuilder.Append("<Image ");

                // Add the xaml image width property
                imageStringBuilder.Append(" Width=\"");
                double width;
                if (formatState.ImageScaleWidth != 0)
                {
                    width = formatState.ImageWidth * (formatState.ImageScaleWidth / 100);
                }
                else
                {
                    width = formatState.ImageWidth;
                }
                imageStringBuilder.Append(width.ToString(CultureInfo.InvariantCulture));
                imageStringBuilder.Append("\"");

                // Add the xaml image height property
                imageStringBuilder.Append(" Height=\"");
                double height = formatState.ImageHeight * (formatState.ImageScaleHeight / 100);
                if (formatState.ImageScaleHeight != 0)
                {
                    height = formatState.ImageHeight * (formatState.ImageScaleHeight / 100);
                }
                else
                {
                    height = formatState.ImageHeight;
                }
                imageStringBuilder.Append(height.ToString(CultureInfo.InvariantCulture));
                imageStringBuilder.Append("\"");

                // Add the xaml image stretch property
                imageStringBuilder.Append(" Stretch=\"Fill");
                imageStringBuilder.Append("\"");


                // Add the xaml image close tag
                imageStringBuilder.Append(">");

                // Add the image source property as the complex property
                // This is for specifying BitmapImage.CacheOption as OnLoad instead of
                // the default OnDemand option.
                imageStringBuilder.Append("<Image.Source>");
                imageStringBuilder.Append("<BitmapImage ");
                imageStringBuilder.Append("UriSource=\"");
                imageStringBuilder.Append(imagePartUriString);
                imageStringBuilder.Append("\" ");
                imageStringBuilder.Append("CacheOption=\"OnLoad\" ");
                imageStringBuilder.Append("/>");
                imageStringBuilder.Append("</Image.Source>");
                imageStringBuilder.Append("</Image>");

                // Set Xaml for image element
                dnImage.Xaml = imageStringBuilder.ToString();

                // Insert the image document node to the document node array
                DocumentNodeArray dna = _converterState.DocumentNodeArray;
                dna.Push(dnImage);
                dna.CloseAt(dna.Count - 1);
            }
            else
            {
                // Skip the image data if the image type is unknown or WpfPayload is null
                _lexer.AdvanceForImageData();
            }
        }
        internal void ConstrainFontPropagation(FormatState fsOrig)
        {
            // We only output certain font properties at the paragraph level.  Ensure the paragraph's formatstate
            // only records those properties that are actually written there, so that inline nodes properly
            // generate the result.
            FormatState.SetCharDefaults();
            FormatState.Font = fsOrig.Font;
            FormatState.FontSize = fsOrig.FontSize;
            FormatState.Bold = fsOrig.Bold;
            FormatState.Italic = fsOrig.Italic;

            // No, lang can't be written at paragraph level since I have no way of turning it "off", e.g. if
            // \lang specified for \par but not for inline text.
            // FormatState.LangCur = fsOrig.LangCur;

            // No, font color can't be written at paragraph level since I have no way of turning it "off" once
            // I've turned it on, so "automatic" color values can't be encoded.  I'll just have to skip it here.
            // FormatState.CF = fsOrig.CF;

            // No, text decorations can't be written at paragraph level since they don't propagate.
            // FormatState.UL = fsOrig.UL;
            // FormatState.Strike = fsOrig.Strike;
        }
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------

        #region Constructors

        internal DocumentNode(DocumentNodeType documentNodeType)
        {
            _type = documentNodeType;
            _bPending = true;
            _childCount = 0;
            _index = -1;
            _dna = null;
            _parent = null;
            _bTerminated = false;
            _bMatched = false;
            _bHasMarkerContent = false;
            _sCustom = null;
            _nRowSpan = 1;
            _nColSpan = 1;
            _nVirtualListLevel = -1;
            _csa = null;

            _formatState = new FormatState();
            _contentBuilder = new StringBuilder();
        }
        private int GetMatchedMarkList(FormatState formatState, MarkerList mlHave, MarkerList mlWant)
        {
            // The ones we have are only "good" if the styles match what we want.
            int nMatch = 0;
            for (; nMatch < mlHave.Count && nMatch < mlWant.Count; nMatch++)
            {
                if (!formatState.IsContinue)
                {
                    MarkerListEntry eHave = mlHave.EntryAt(nMatch);
                    MarkerListEntry eWant = mlWant.EntryAt(nMatch);

                    if (eHave.Marker != eWant.Marker
                        || eHave.ILS != eWant.ILS
                        || eHave.StartIndexDefault != eWant.StartIndexDefault
                        || eWant.StartIndexOverride >= 0)
                    {
                        break;
                    }
                }
            }

            return nMatch;
        }
        internal void HandleShapeTokens(RtfToken token, FormatState formatState)
        {
            DocumentNodeArray dna = _converterState.DocumentNodeArray;
            FormatState fsCur = _converterState.PreviousTopFormatState(0);
            FormatState fsOld = _converterState.PreviousTopFormatState(1);
            if (fsCur == null || fsOld == null)
            {
                return;
            }

            switch (token.RtfControlWordInfo.Control)
            {
                case RtfControlWord.Ctrl_DO:
                    // Just propagate destination through this keyword.
                    fsCur.RtfDestination = fsOld.RtfDestination;
                    break;
                case RtfControlWord.Ctrl_SHPRSLT:
                    if (fsOld.IsContentDestination)
                    {
                        fsCur.RtfDestination = RtfDestination.DestShape;
                    }
                    break;
                case RtfControlWord.Ctrl_DPTXBXTEXT:
                    if (fsOld.IsContentDestination)
                    {
                        // Track the destination so I can recognize when we leave this scope.
                        fsCur.RtfDestination = RtfDestination.DestShapeResult;

                        // Wrap any inline content that occurs before this shape anchor in a paragraph,
                        // since the shape content itself will be block level.
                        WrapPendingInlineInParagraph(token, formatState);

                        DocumentNodeType t = dna.GetTableScope();
                        if (t != DocumentNodeType.dnParagraph)
                        {
                            if (t == DocumentNodeType.dnTableBody)
                            {
                                // If row has been closed, close overall table as well.
                                int nAt = dna.FindPending(DocumentNodeType.dnTable);
                                if (nAt >= 0)
                                {
                                    dna.CloseAt(nAt);
                                    dna.CoalesceChildren(_converterState, nAt);
                                }
                            }
                            else
                            {
                                // If I'm inside a table, reopen last cell to insert shape contents.  Otherwise
                                // table gets torqued.
                                dna.OpenLastCell();
                            }
                        }

                        // The shape node generates no output but plays a large role in changing the
                        // behavior of the "FindPending" routines to keep from looking outside this scope.
                        DocumentNode dn = new DocumentNode(DocumentNodeType.dnShape);
                        formatState.SetParaDefaults();
                        formatState.SetCharDefaults();
                        dn.FormatState = new FormatState(formatState);
                        dna.Push(dn);
                    }
                    break;
                case RtfControlWord.Ctrl_SHPPICT:
                    // If this occurs in listtext context, mark listtext as non-empty.
                    int ndnListText = dna.FindPending(DocumentNodeType.dnListText);
                    if (ndnListText >= 0)
                    {
                        DocumentNode dnListText = dna.EntryAt(ndnListText);

                        dnListText.HasMarkerContent = true;
                    }

                    // Keep the rtf destination as the list picture to skip the list picture
                    if (fsOld.RtfDestination == RtfDestination.DestListPicture)
                    {
                        formatState.RtfDestination = RtfDestination.DestListPicture;
                    }
                    else
                    {
                        formatState.RtfDestination = RtfDestination.DestShapePicture;
                    }

                    break;
                case RtfControlWord.Ctrl_NONSHPPICT:
                    formatState.RtfDestination = RtfDestination.DestNoneShapePicture;
                    break;
            }
        }
        internal void HandleListTokens(RtfToken token, FormatState formatState)
        {
            ListTable listTable = _converterState.ListTable;
            ListOverrideTable listOverrideTable = _converterState.ListOverrideTable;

            FormatState fsCur = _converterState.PreviousTopFormatState(0);
            FormatState fsOld = _converterState.PreviousTopFormatState(1);
            if (fsCur == null || fsOld == null)
            {
                return;
            }

            switch (token.RtfControlWordInfo.Control)
            {
                case RtfControlWord.Ctrl_LIST:
                    if (formatState.RtfDestination == RtfDestination.DestListTable)
                    {
                        ListTableEntry listTableEntry = listTable.AddEntry();
                    }
                    break;

                case RtfControlWord.Ctrl_LISTTEMPLATEID:
                    {
                        ListTableEntry listTableEntry = listTable.CurrentEntry;
                        if (listTableEntry != null)
                        {
                            listTableEntry.TemplateID = token.Parameter;
                        }
                    }
                    break;

                case RtfControlWord.Ctrl_LISTHYBRID:
                case RtfControlWord.Ctrl_LISTSIMPLE:
                    {
                        ListTableEntry listTableEntry = listTable.CurrentEntry;
                        if (listTableEntry != null)
                        {
                            listTableEntry.Simple = token.RtfControlWordInfo.Control == RtfControlWord.Ctrl_LISTSIMPLE;
                        }
                    }
                    break;

                case RtfControlWord.Ctrl_LISTLEVEL:
                    {
                        formatState.RtfDestination = RtfDestination.DestListLevel;
                        ListLevelTable levels = GetControllingLevelTable();
                        if (levels != null)
                        {
                            ListLevel listLevel = levels.AddEntry();
                        }
                    }
                    break;

                case RtfControlWord.Ctrl_LISTTEXT:
                    if (fsOld.IsContentDestination || formatState.IsHidden)
                    {
                        formatState.RtfDestination = RtfDestination.DestListText;
                        DocumentNodeArray dna = _converterState.DocumentNodeArray;
                        DocumentNode dnl = new DocumentNode(DocumentNodeType.dnListText);

                        dnl.FormatState = new FormatState(formatState);
                        dna.Push(dnl);
                    }
                    break;

                case RtfControlWord.Ctrl_LEVELNFC:
                case RtfControlWord.Ctrl_LEVELNFCN:
                    {
                        ListLevelTable levels = GetControllingLevelTable();
                        if (levels != null)
                        {
                            ListLevel listLevel = levels.CurrentEntry;
                            if (listLevel != null)
                            {
                                listLevel.Marker = (MarkerStyle)token.Parameter;
                            }
                        }
                    }
                    break;
                case RtfControlWord.Ctrl_LEVELJC:
                case RtfControlWord.Ctrl_LEVELJCN:
                    // NB: Marker alignment not supported in XAML.
                    break;

                case RtfControlWord.Ctrl_LEVELFOLLOW:
                    break;

                case RtfControlWord.Ctrl_LEVELSTARTAT:
                    {
                        ListLevelTable levels = GetControllingLevelTable();
                        if (levels != null)
                        {
                            ListLevel listLevel = levels.CurrentEntry;
                            if (listLevel != null)
                            {
                                listLevel.StartIndex = token.Parameter;
                            }
                            else
                            {
                                // This is the case where the list override *only* specifies startat override.
                                ListOverride lo = GetControllingListOverride();

                                if (lo != null)
                                {
                                    lo.StartIndex = token.Parameter;
                                }
                            }
                        }
                    }
                    break;

                case RtfControlWord.Ctrl_LEVELSPACE:
                    break;
                case RtfControlWord.Ctrl_LEVELINDENT:
                    break;
                case RtfControlWord.Ctrl_LEVELTEXT:
                    break;
                case RtfControlWord.Ctrl_LEVELTEMPLATEID:
                    break;

                case RtfControlWord.Ctrl_LISTID:
                    {
                        if (formatState.RtfDestination == RtfDestination.DestListOverride)
                        {
                            ListOverride listOverride = listOverrideTable.CurrentEntry;
                            if (listOverride != null)
                            {
                                listOverride.ID = token.Parameter;
                            }
                        }
                        else
                        {
                            ListTableEntry listTableEntry = listTable.CurrentEntry;
                            if (listTableEntry != null)
                            {
                                listTableEntry.ID = token.Parameter;
                            }
                        }
                    }
                    break;

                case RtfControlWord.Ctrl_LEVELNUMBERS:
                    break;

                case RtfControlWord.Ctrl_LISTOVERRIDE:
                    {
                        FormatState previousFormatState = _converterState.PreviousTopFormatState(1);

                        if (previousFormatState.RtfDestination == RtfDestination.DestListOverrideTable)
                        {
                            formatState.RtfDestination = RtfDestination.DestListOverride;

                            ListOverride listOverride = listOverrideTable.AddEntry();
                        }
                    }
                    break;

                case RtfControlWord.Ctrl_LS:
                    if (formatState.RtfDestination == RtfDestination.DestListOverride)
                    {
                        ListOverride listOverride = listOverrideTable.CurrentEntry;
                        if (listOverride != null)
                        {
                            listOverride.Index = token.Parameter;
                        }

                    }
                    break;
            }
        }
Esempio n. 12
0
        private bool WriteParagraphListInfo(DocumentNode dnThis, FormatState fsThis)
        { 
            bool bOutControl = false;

            bool bNewStyle = GenerateListTables;
            if (dnThis.ListLabel != null) 
            {
                DocumentNode dnList = dnThis.GetParentOfType(DocumentNodeType.dnList); 
                if (dnList != null) 
                {
                    // Old style list info for RichEdit and other non-Word client compat if I can. 
                    // Only do this for simple, non multi-level lists.
                    if (bNewStyle && dnList.FormatState.PNLVL == 1)
                    {
                        bNewStyle = false; 
                    }
 
                    if (bNewStyle) 
                    {
                        _rtfBuilder.Append("{\\listtext "); 
                        _rtfBuilder.Append(dnThis.ListLabel);
                        if (dnList.FormatState.Marker != MarkerStyle.MarkerBullet
                            && dnList.FormatState.Marker != MarkerStyle.MarkerNone)
                        { 
                            _rtfBuilder.Append(".");
                        } 
                        _rtfBuilder.Append("\\tab}"); 

                        // NB: RichEdit requires \ls keyword to occur immediately after \listtext 
                        if (fsThis.ILS > 0)
                        {
                            _rtfBuilder.Append("\\ls");
                            _rtfBuilder.Append(fsThis.ILS.ToString(CultureInfo.InvariantCulture)); 
                            bOutControl = true;
                        } 
                        if (fsThis.ILVL > 0) 
                        {
                            _rtfBuilder.Append("\\ilvl"); 
                            _rtfBuilder.Append(fsThis.ILVL.ToString(CultureInfo.InvariantCulture));
                            bOutControl = true;
                        }
                    } 
                    else
                    { 
                        _rtfBuilder.Append("{\\pntext "); 
                        _rtfBuilder.Append(dnThis.ListLabel);
                        if (dnList.FormatState.Marker != MarkerStyle.MarkerBullet 
                            && dnList.FormatState.Marker != MarkerStyle.MarkerNone)
                        {
                            _rtfBuilder.Append(".");
                        } 
                        _rtfBuilder.Append("\\tab}{\\*\\pn");
                        _rtfBuilder.Append(Converters.MarkerStyleToOldRTFString(dnList.FormatState.Marker)); 
                        if (fsThis.ListLevel > 0 && dnList.FormatState.PNLVL > 1) 
                        {
                            _rtfBuilder.Append("\\pnlvl"); 
                            _rtfBuilder.Append(fsThis.ListLevel.ToString(CultureInfo.InvariantCulture));
                        }
                        if (fsThis.FI > 0)
                        { 
                            _rtfBuilder.Append("\\pnhang");
                        } 
                        if (fsThis.StartIndex >= 0) 
                        {
                            _rtfBuilder.Append("\\pnstart"); 
                            _rtfBuilder.Append(fsThis.StartIndex.ToString(CultureInfo.InvariantCulture));
                        }
                        if (dnList.FormatState.Marker == MarkerStyle.MarkerBullet)
                        { 
                            _rtfBuilder.Append("{\\pntxtb\\'B7}}");
                        } 
                        else if (dnList.FormatState.Marker == MarkerStyle.MarkerNone) 
                        {
                            _rtfBuilder.Append("{\\pntxta }{\\pntxtb }}"); 
                        }
                        else
                        {
                            _rtfBuilder.Append("{\\pntxta .}}"); 
                        }
 
                        // Already terminated with curly, no need for extra space. 
                        bOutControl = false;
                    } 
                }
            }

            return bOutControl; 
        }
Esempio n. 13
0
        private bool WriteParagraphFontInfo(DocumentNode dnThis, FormatState fsThis, FormatState fsParent)
        {
            int nStart = dnThis.Index + 1;
            int nEnd = dnThis.Index + dnThis.ChildCount; 
            int nAt;
            DocumentNodeArray dna = _converterState.DocumentNodeArray; 
 
            bool bOutControl = false;
 
            // In order to minimize RTF output, pull fontsize and font info into paragraph level if possible
            long fsAll = -2;
            long fontAll = -2;
            for (nAt = nStart; nAt <= nEnd; nAt++) 
            {
                DocumentNode dnChild = dna.EntryAt(nAt); 
 
                if (dnChild.Parent == dnThis)
                { 
                    if (fsAll == -2)
                    {
                        fsAll = dnChild.FormatState.FontSize;
                    } 
                    else if (fsAll != dnChild.FormatState.FontSize)
                    { 
                        fsAll = -3; 
                    }
                    if (fontAll == -2) 
                    {
                        fontAll = dnChild.FormatState.Font;
                    }
                    else if (fontAll != dnChild.FormatState.Font) 
                    {
                        fontAll = -3; 
                    } 
                }
            } 
            if (fsAll >= 0)
            {
                fsThis.FontSize = fsAll;
            } 
            if (fontAll >= 0)
            { 
                fsThis.Font = fontAll; 
            }
 
            // Workaround for Word 11 \f behavior.  See bug 1636475.
            // Word 11 does not respect \f applied above the paragraph
            // level with \rtlpara.  This is a targeted work-around
            // which is probably not complete, but additional repros 
            // are currently lacking.
            bool isTopLevelParagraph = dnThis.Type == DocumentNodeType.dnParagraph && 
                                       dnThis.Parent != null && 
                                       dnThis.Parent.Type == DocumentNodeType.dnSection &&
                                       dnThis.Parent.Parent == null; 

            if (fsThis.FontSize != fsParent.FontSize)
            {
                _rtfBuilder.Append("\\fs"); 
                _rtfBuilder.Append(fsThis.FontSize.ToString(CultureInfo.InvariantCulture));
                bOutControl = true; 
            } 
            if (fsThis.Font != fsParent.Font || isTopLevelParagraph)
            { 
                _rtfBuilder.Append("\\f");
                _rtfBuilder.Append(fsThis.Font.ToString(CultureInfo.InvariantCulture));
                bOutControl = true;
            } 
            if (fsThis.Bold != fsParent.Bold)
            { 
                _rtfBuilder.Append("\\b"); 
                bOutControl = true;
            } 
            if (fsThis.Italic != fsParent.Italic)
            {
                _rtfBuilder.Append("\\i");
                bOutControl = true; 
            }
            if (fsThis.UL != fsParent.UL) 
            { 
                _rtfBuilder.Append("\\ul");
                bOutControl = true; 
            }
            if (fsThis.Strike != fsParent.Strike)
            {
                _rtfBuilder.Append("\\strike"); 
                bOutControl = true;
            } 
            if (fsThis.CF != fsParent.CF) 
            {
                _rtfBuilder.Append("\\cf"); 
                _rtfBuilder.Append(fsThis.CF.ToString(CultureInfo.InvariantCulture));
                bOutControl = true;
            }
 
            return bOutControl;
        } 
        // Token: 0x060032AD RID: 12973 RVA: 0x000E3CC8 File Offset: 0x000E1EC8
        internal RtfToXamlError Next(RtfToken token, FormatState formatState)
        {
            RtfToXamlError result = RtfToXamlError.None;

            this._rtfLastIndex = this._rtfIndex;
            token.Empty();
            if (this._rtfIndex >= this._rtfBytes.Length)
            {
                token.Type = RtfTokenType.TokenEOF;
                return(result);
            }
            int rtfIndex = this._rtfIndex;

            byte[] rtfBytes  = this._rtfBytes;
            int    rtfIndex2 = this._rtfIndex;

            this._rtfIndex = rtfIndex2 + 1;
            byte b = rtfBytes[rtfIndex2];

            if (b <= 13)
            {
                if (b == 0)
                {
                    token.Type = RtfTokenType.TokenNullChar;
                    return(result);
                }
                if (b == 10 || b == 13)
                {
                    token.Type = RtfTokenType.TokenNewline;
                    return(result);
                }
            }
            else if (b != 92)
            {
                if (b == 123)
                {
                    token.Type = RtfTokenType.TokenGroupStart;
                    return(result);
                }
                if (b == 125)
                {
                    token.Type = RtfTokenType.TokenGroupEnd;
                    return(result);
                }
            }
            else
            {
                if (this._rtfIndex >= this._rtfBytes.Length)
                {
                    token.Type = RtfTokenType.TokenInvalid;
                    return(result);
                }
                if (this.IsControlCharValid(this.CurByte))
                {
                    int rtfIndex3 = this._rtfIndex;
                    this.SetRtfIndex(token, rtfIndex3);
                    token.Text = this.CurrentEncoding.GetString(this._rtfBytes, rtfIndex3 - 1, this._rtfIndex - rtfIndex);
                    return(result);
                }
                if (this.CurByte == 39)
                {
                    this._rtfIndex--;
                    return(this.NextText(token));
                }
                if (this.CurByte == 42)
                {
                    this._rtfIndex++;
                    token.Type = RtfTokenType.TokenDestination;
                    return(result);
                }
                token.Type = RtfTokenType.TokenTextSymbol;
                token.Text = this.CurrentEncoding.GetString(this._rtfBytes, this._rtfIndex, 1);
                this._rtfIndex++;
                return(result);
            }
            this._rtfIndex--;
            if (formatState == null || formatState.RtfDestination != RtfDestination.DestPicture)
            {
                return(this.NextText(token));
            }
            token.Type = RtfTokenType.TokenPictureData;
            return(result);
        }
 internal void HandlePage(RtfToken token, FormatState formatState)
 {
     WrapPendingInlineInParagraph(token, formatState);
 }
        internal void HandleOldListTokens(RtfToken token, FormatState formatState)
        {
            FormatState fsCur = _converterState.PreviousTopFormatState(0);
            FormatState fsOld = _converterState.PreviousTopFormatState(1);
            if (fsCur == null || fsOld == null)
            {
                return;
            }

            // If we're in the PN destination, we push marker setting into the previous format state.
            if (formatState.RtfDestination == RtfDestination.DestPN)
            {
                formatState = fsOld;
            }

            switch (token.RtfControlWordInfo.Control)
            {
                case RtfControlWord.Ctrl_PNLVL:
                    formatState.PNLVL = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_PNLVLBLT:
                    formatState.Marker = MarkerStyle.MarkerBullet;
                    formatState.IsContinue = false;
                    break;
                case RtfControlWord.Ctrl_PNLVLBODY:
                    formatState.Marker = MarkerStyle.MarkerArabic;
                    formatState.IsContinue = false;
                    break;
                case RtfControlWord.Ctrl_PNLVLCONT:
                    formatState.IsContinue = true;
                    break;
                case RtfControlWord.Ctrl_PNCARD:
                    formatState.Marker = MarkerStyle.MarkerCardinal;
                    break;
                case RtfControlWord.Ctrl_PNDEC:
                    formatState.Marker = MarkerStyle.MarkerArabic;
                    break;
                case RtfControlWord.Ctrl_PNUCLTR:
                    formatState.Marker = MarkerStyle.MarkerUpperAlpha;
                    break;
                case RtfControlWord.Ctrl_PNUCRM:
                    formatState.Marker = MarkerStyle.MarkerUpperRoman;
                    break;
                case RtfControlWord.Ctrl_PNLCLTR:
                    formatState.Marker = MarkerStyle.MarkerLowerAlpha;
                    break;
                case RtfControlWord.Ctrl_PNLCRM:
                    formatState.Marker = MarkerStyle.MarkerLowerRoman;
                    break;
                case RtfControlWord.Ctrl_PNORD:
                    formatState.Marker = MarkerStyle.MarkerOrdinal;
                    break;
                case RtfControlWord.Ctrl_PNORDT:
                    formatState.Marker = MarkerStyle.MarkerOrdinal;
                    break;
                case RtfControlWord.Ctrl_PNBIDIA:
                    formatState.Marker = MarkerStyle.MarkerArabic;
                    break;
                case RtfControlWord.Ctrl_PNBIDIB:
                    formatState.Marker = MarkerStyle.MarkerArabic;
                    break;
                case RtfControlWord.Ctrl_PN:
                    formatState.RtfDestination = RtfDestination.DestPN;
                    fsOld.Marker = MarkerStyle.MarkerBullet;
                    break;
                case RtfControlWord.Ctrl_PNTXTA:
                    // Leave with unknown destination so text is tossed.
                    break;
                case RtfControlWord.Ctrl_PNTXTB:
                    // Leave with unknown destination so text is tossed.
                    break;
                case RtfControlWord.Ctrl_PNTEXT:
                    if (fsOld.IsContentDestination || formatState.IsHidden)
                    {
                        fsCur.RtfDestination = RtfDestination.DestListText;
                        DocumentNodeArray dna = _converterState.DocumentNodeArray;
                        DocumentNode dnl = new DocumentNode(DocumentNodeType.dnListText);

                        dnl.FormatState = new FormatState(formatState);
                        dna.Push(dnl);
                    }
                    break;
                case RtfControlWord.Ctrl_PNSTART:
                    formatState.StartIndex = token.Parameter;
                    break;

                default:
                    formatState.Marker = MarkerStyle.MarkerBullet;
                    break;
            }
        }
        internal void HandleTableTokens(RtfToken token, FormatState formatState)
        {
            FormatState fsCur = _converterState.PreviousTopFormatState(0);
            FormatState fsOld = _converterState.PreviousTopFormatState(1);
            if (fsCur == null || fsOld == null)
            {
                return;
            }

            // Propagate current destination into nested table props destination keyword
            if (token.RtfControlWordInfo.Control == RtfControlWord.Ctrl_NESTTABLEPROPS)
            {
                fsCur.RtfDestination = fsOld.RtfDestination;
            }

            if (!formatState.IsContentDestination)
            {
                return;
            }

            DocumentNodeArray dna = _converterState.DocumentNodeArray;
            int nCellAt;
            bool bOldHide = formatState.IsHidden;

            switch (token.RtfControlWordInfo.Control)
            {
                case RtfControlWord.Ctrl_CELL:
                    // Force a paragraph
                    // Set intbl and itap values, then use paragraph code.
                    formatState.IsInTable = true;
                    formatState.ITAP = 1;
                    formatState.IsHidden = false;
                    HandlePara(token, formatState);
                    formatState.IsHidden = bOldHide;
                    nCellAt = dna.FindPending(DocumentNodeType.dnCell);
                    if (nCellAt >= 0)
                    {
                        dna.CloseAt(nCellAt);

                        // Don't coalesce cell tag itself, since I might not have yet read the properties
                        // I need for writing out the cell attributes.
                        // Actually, even paragraph tags inside cell needs to have table info.
                        // dna.CoalesceOnlyChildren(_converterState, nCellAt);
                    }
                    break;

                case RtfControlWord.Ctrl_NESTCELL:
                    // Force a paragraph out.
                    formatState.IsHidden = false;
                    HandlePara(token, formatState);
                    formatState.IsHidden = bOldHide;

                    // If we encounter an open row before an open cell, we need to open a new cell.
                    // Or if we only have one level of table currently open.
                    int nOpenCells = dna.CountOpenCells();
                    DocumentNodeType scope = dna.GetTableScope();

                    if (scope != DocumentNodeType.dnCell || nOpenCells < 2)
                    {
                        HandlePara(token, formatState);
                    }

                    // Now close the currently open cell
                    nCellAt = dna.FindPending(DocumentNodeType.dnCell);
                    if (nCellAt >= 0)
                    {
                        dna.CloseAt(nCellAt);

                        // Don't coalesce cell tag itself, since I might not have yet read the properties
                        // I need for writing out the cell attributes.
                        // Actually, even paragraph tags inside cell needs to have table info.
                        // dna.CoalesceOnlyChildren(_converterState, nCellAt);
                    }
                    break;

                case RtfControlWord.Ctrl_TROWD:
                    formatState.IsHidden = false;
                    formatState.SetRowDefaults();
                    formatState.IsHidden = bOldHide;
                    break;

                case RtfControlWord.Ctrl_ROW:
                case RtfControlWord.Ctrl_NESTROW:
                    // Word puts out \row properties both before and after the cell contents.
                    // \nestrow properties are only put out *after* the cell contents.
                    formatState.IsHidden = false;
                    int nRowAt = dna.FindPending(DocumentNodeType.dnRow);
                    if (nRowAt >= 0)
                    {
                        DocumentNode dnRow = dna.EntryAt(nRowAt);
                        if (formatState.RowFormat != null)
                        {
                            dnRow.FormatState.RowFormat = new RowFormat(formatState.RowFormat);
                            dnRow.FormatState.RowFormat.CanonicalizeWidthsFromRTF();

                            // Also cache the row information in the table node
                            int nTable = dna.FindPendingFrom(DocumentNodeType.dnTable, nRowAt - 1, -1);
                            if (nTable >= 0)
                            {
                                DocumentNode dnTable = dna.EntryAt(nTable);
                                if (!dnTable.FormatState.HasRowFormat)
                                {
                                    dnTable.FormatState.RowFormat = dnRow.FormatState.RowFormat;
                                }
                            }
                        }

                        // Anomalous, but possible for illegal content.
                        ProcessPendingTextAtRowEnd();

                        dna.CloseAt(nRowAt);

                        // Don't coalesce - I need to examine all cells before writing things out
                        // dna.CoalesceChildren(_converterState, nRowAt);
                    }
                    formatState.IsHidden = bOldHide;
                    break;

                case RtfControlWord.Ctrl_NESTTABLEPROPS:
                    // Handled above.
                    break;
            }
        }
        internal void HandleTableProperties(RtfToken token, FormatState formatState)
        {
            if (!formatState.IsContentDestination)
            {
                return;
            }

            CellFormat cf = null;

            switch (token.RtfControlWordInfo.Control)
            {
                case RtfControlWord.Ctrl_TRGAPH:
                    break;
                case RtfControlWord.Ctrl_TRLEFT:
                    formatState.RowFormat.Trleft = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRQC:
                    // Specifies overall alignment of the table row - ignore for now.
                    break;
                case RtfControlWord.Ctrl_TRQL:
                    // Specifies overall alignment of the table row - ignore for now.
                    break;
                case RtfControlWord.Ctrl_TRQR:
                    // Specifies overall alignment of the table row - ignore for now.
                    break;
                case RtfControlWord.Ctrl_TRPADDL:
                    formatState.RowFormat.RowCellFormat.PaddingLeft = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRPADDR:
                    formatState.RowFormat.RowCellFormat.PaddingRight = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRPADDB:
                    formatState.RowFormat.RowCellFormat.PaddingBottom = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRPADDT:
                    formatState.RowFormat.RowCellFormat.PaddingTop = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRPADDFL:
                    // zero value indicates ignore trpaddl, three means treat it as twips
                    break;
                case RtfControlWord.Ctrl_TRPADDFT:
                    // zero value indicates ignore trpaddt, three means treat it as twips
                    break;
                case RtfControlWord.Ctrl_TRPADDFB:
                    // zero value indicates ignore trpaddb, three means treat it as twips
                    break;
                case RtfControlWord.Ctrl_TRPADDFR:
                    // zero value indicates ignore trpaddr, three means treat it as twips
                    break;
                case RtfControlWord.Ctrl_TRSPDFB:
                    if (token.Parameter == 0)
                        formatState.RowFormat.RowCellFormat.SpacingBottom = 0;
                    break;
                case RtfControlWord.Ctrl_TRSPDFL:
                    if (token.Parameter == 0)
                        formatState.RowFormat.RowCellFormat.SpacingLeft = 0;
                    break;
                case RtfControlWord.Ctrl_TRSPDFR:
                    if (token.Parameter == 0)
                        formatState.RowFormat.RowCellFormat.SpacingRight = 0;
                    break;
                case RtfControlWord.Ctrl_TRSPDFT:
                    if (token.Parameter == 0)
                        formatState.RowFormat.RowCellFormat.SpacingTop = 0;
                    break;
                case RtfControlWord.Ctrl_TRSPDB:
                    formatState.RowFormat.RowCellFormat.SpacingBottom = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRSPDL:
                    formatState.RowFormat.RowCellFormat.SpacingLeft = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRSPDR:
                    formatState.RowFormat.RowCellFormat.SpacingRight = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRSPDT:
                    formatState.RowFormat.RowCellFormat.SpacingTop = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRWWIDTH:
                    // Row (table) width
                    formatState.RowFormat.WidthRow.Value = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRFTSWIDTH:
                    // Units for WWIDTH (0 - ignore, 1 - auto, 2 - 50ths of a percent, 3 - twips)
                    if (Validators.IsValidWidthType(token.Parameter))
                        formatState.RowFormat.WidthRow.Type = (WidthType)token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRWWIDTHB:
                    // Space before row width
                    break;
                case RtfControlWord.Ctrl_TRFTSWIDTHB:
                    break;
                case RtfControlWord.Ctrl_TRWWIDTHA:
                    // Space after row width
                    formatState.RowFormat.WidthA.Value = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRFTSWIDTHA:
                    if (Validators.IsValidWidthType(token.Parameter))
                        formatState.RowFormat.WidthA.Type = (WidthType)token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRAUTOFIT:
                    if (token.ToggleValue > 0)
                        formatState.RowFormat.WidthRow.SetDefaults();
                    break;
                case RtfControlWord.Ctrl_CLWWIDTH:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.Width.Value = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_CLFTSWIDTH:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    if (Validators.IsValidWidthType(token.Parameter))
                        cf.Width.Type = (WidthType)token.Parameter;
                    break;
                case RtfControlWord.Ctrl_TRBRDRT:
                    ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderTop;
                    break;
                case RtfControlWord.Ctrl_TRBRDRB:
                    ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderBottom;
                    break;
                case RtfControlWord.Ctrl_TRBRDRR:
                    ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderRight;
                    break;
                case RtfControlWord.Ctrl_TRBRDRL:
                    ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderLeft;
                    break;
                case RtfControlWord.Ctrl_TRBRDRV:
                    ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderLeft;
                    break;
                case RtfControlWord.Ctrl_TRBRDRH:
                    ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderTop;
                    break;
                case RtfControlWord.Ctrl_CLVERTALT:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.VAlign = VAlign.AlignTop;
                    break;
                case RtfControlWord.Ctrl_CLVERTALB:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.VAlign = VAlign.AlignBottom;
                    break;
                case RtfControlWord.Ctrl_CLVERTALC:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.VAlign = VAlign.AlignCenter;
                    break;
                case RtfControlWord.Ctrl_CLSHDNG:
                    // Cell shading in 100's of a percent
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.Shading = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_CLSHDRAWNIL:
                    // No cell shading - clear color for now
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.Shading = -1;
                    cf.CB = -1;
                    cf.CF = -1;
                    break;
                case RtfControlWord.Ctrl_CLBRDRB:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    ConverterState.CurrentBorder = cf.BorderBottom;
                    break;
                case RtfControlWord.Ctrl_CLBRDRR:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    ConverterState.CurrentBorder = cf.BorderRight;
                    break;
                case RtfControlWord.Ctrl_CLBRDRT:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    ConverterState.CurrentBorder = cf.BorderTop;
                    break;
                case RtfControlWord.Ctrl_CLBRDRL:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    ConverterState.CurrentBorder = cf.BorderLeft;
                    break;
                case RtfControlWord.Ctrl_CLCBPAT:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.CB = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_CLCFPAT:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.CF = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_CLPADL:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.PaddingLeft = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_CLPADR:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.PaddingRight = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_CLPADB:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.PaddingBottom = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_CLPADT:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.PaddingTop = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_CLPADFL:
                    // zero value indicates ignore clpadl, three means treat it as twips
                    break;
                case RtfControlWord.Ctrl_CLPADFT:
                    // zero value indicates ignore clpadt, three means treat it as twips
                    break;
                case RtfControlWord.Ctrl_CLPADFB:
                    // zero value indicates ignore clpadb, three means treat it as twips
                    break;
                case RtfControlWord.Ctrl_CLPADFR:
                    // zero value indicates ignore clpadr, three means treat it as twips
                    break;
                case RtfControlWord.Ctrl_CELLX:
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.CellX = token.Parameter;
                    cf.IsPending = false;
                    break;
                case RtfControlWord.Ctrl_RTLROW:
                    formatState.RowFormat.Dir = DirState.DirRTL;
                    break;
                case RtfControlWord.Ctrl_LTRROW:
                    formatState.RowFormat.Dir = DirState.DirLTR;
                    break;

                // Cell merging
                case RtfControlWord.Ctrl_CLMGF:
                    // First cell in range of table cells to be merged.
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.IsHMergeFirst = true;
                    break;
                case RtfControlWord.Ctrl_CLMRG:
                    // Contents of this cell are merged with those of the preceding cell.
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.IsHMerge = true;
                    break;
                case RtfControlWord.Ctrl_CLVMGF:
                    // First cell in range of cells to be vertically merged.
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.IsVMergeFirst = true;
                    break;
                case RtfControlWord.Ctrl_CLVMRG:
                    // Contents of this cell are vertically merged with those of the preceding cell.
                    cf = formatState.RowFormat.CurrentCellFormat();
                    cf.IsVMerge = true;
                    break;

                // General borders, not just tables
                case RtfControlWord.Ctrl_BRDRL:
                    // Left paragraph border
                    ConverterState.CurrentBorder = formatState.ParaBorder.BorderLeft;
                    break;
                case RtfControlWord.Ctrl_BRDRR:
                    // Right paragraph border
                    ConverterState.CurrentBorder = formatState.ParaBorder.BorderRight;
                    break;
                case RtfControlWord.Ctrl_BRDRT:
                    // Top paragraph border
                    ConverterState.CurrentBorder = formatState.ParaBorder.BorderTop;
                    break;
                case RtfControlWord.Ctrl_BRDRB:
                    // Bottom paragraph border
                    ConverterState.CurrentBorder = formatState.ParaBorder.BorderBottom;
                    break;
                case RtfControlWord.Ctrl_BOX:
                    // All four borders
                    ConverterState.CurrentBorder = formatState.ParaBorder.BorderAll;
                    break;
                case RtfControlWord.Ctrl_BRDRNIL:
                    // No borders
                    ConverterState.CurrentBorder = null;
                    break;
                case RtfControlWord.Ctrl_BRSP:
                    // Space in twips between borders and paragraph
                    formatState.ParaBorder.Spacing = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_BRDRTBL:
                    // No cell borders
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderNone;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRART:
                    // Art border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRBAR:
                    // Border on outside edge of page (treat as BRDRL for XAML)
                    break;
                case RtfControlWord.Ctrl_BRDRBTW:
                    break;
                case RtfControlWord.Ctrl_BRDRCF:
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.CF = token.Parameter;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRDASH:
                    // Dashed border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRDASHD:
                    // Dash dot border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRDASHDD:
                    // Dot dot dash border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRDASHDOTSTR:
                    // Dash-dot border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRDASHSM:
                    // Small dash border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRDB:
                    // Double border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderDouble;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRDOT:
                    // Dotted border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDREMBOSS:
                    // Emboss-style border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRENGRAVE:
                    // Engrave-style border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRFRAME:
                    // Frame-style border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRHAIR:
                    // Hairline border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRINSET:
                    // Inset border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDROUTSET:
                    // Outset border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRS:
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRSH:
                    // Shadow border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRTH:
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderDouble;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRTHTNLG:
                    // Thick-thin (large) border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRTHTNMG:
                    // Thick-thin (medium) border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRTHTNSG:
                    // Thick-thin-thin (thin) border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRTNTHLG:
                    // Thin-thick (large) border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRTNTHMG:
                    // Thick-thin-thin (medium) border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRTNTHSG:
                    // Thick-thin-thin (small) border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRTNTHTNLG:
                    // Thick-thin-thin (large) border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRTNTHTNMG:
                    // Thin-thick-thin (medium) border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRTNTHTNSG:
                    // Thick-thin-thin (small) border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRTRIPLE:
                    // Triple border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRW:
                    // Border thickness
                    if (ConverterState.CurrentBorder != null)
                    {
                        // Note that propset does validation
                        ConverterState.CurrentBorder.Width = token.Parameter;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRNONE:
                    // No borders
                    if (ConverterState.CurrentBorder != null)
                    {
                        // Note that propset does validation
                        ConverterState.CurrentBorder.SetDefaults();
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRWAVY:
                    // Wavy border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderSingle;
                    }
                    break;
                case RtfControlWord.Ctrl_BRDRWAVYDB:
                    // Double border
                    if (ConverterState.CurrentBorder != null)
                    {
                        ConverterState.CurrentBorder.Type = BorderType.BorderDouble;
                    }
                    break;
            }
        }
        internal void ProcessHardLine(RtfToken token, FormatState formatState)
        {
            switch (_converterState.TopFormatState.RtfDestination)
            {
                case RtfDestination.DestNormal:
                case RtfDestination.DestFieldResult:
                case RtfDestination.DestShapeResult:
                case RtfDestination.DestListText:
                    ProcessNormalHardLine(formatState);
                    break;
                case RtfDestination.DestFontTable:
                case RtfDestination.DestFontName:
                    break;
                case RtfDestination.DestColorTable:
                    break;
                case RtfDestination.DestField:
                    break;
                case RtfDestination.DestFieldInstruction:
                case RtfDestination.DestFieldPrivate:
                    ProcessNormalHardLine(formatState);
                    break;
            }

        }
        internal void HandleFieldTokens(RtfToken token, FormatState formatState)
        {
            // Don't start processing fields in non-normal destinatations
            FormatState fsCur = _converterState.PreviousTopFormatState(0);
            FormatState fsOld = _converterState.PreviousTopFormatState(1);
            if (fsCur == null || fsOld == null)
            {
                return;
            }

            switch (token.RtfControlWordInfo.Control)
            {
                case RtfControlWord.Ctrl_FIELD:
                    // Process fields in normal content or nested fields
                    if (!fsOld.IsContentDestination || formatState.IsHidden)
                    {
                        return;
                    }
                    formatState.RtfDestination = RtfDestination.DestField;
                    break;
                case RtfControlWord.Ctrl_FLDRSLT:
                    if (fsOld.RtfDestination != RtfDestination.DestField)
                    {
                        return;
                    }
                    formatState.RtfDestination = RtfDestination.DestFieldResult;
                    break;
                case RtfControlWord.Ctrl_FLDPRIV:
                    if (fsOld.RtfDestination != RtfDestination.DestField)
                    {
                        return;
                    }
                    formatState.RtfDestination = RtfDestination.DestFieldPrivate;
                    break;
                case RtfControlWord.Ctrl_FLDINST:
                    if (fsOld.RtfDestination != RtfDestination.DestField)
                    {
                        return;
                    }
                    formatState.RtfDestination = RtfDestination.DestFieldInstruction;
                    break;
                default:
                    return;
            }

            DocumentNodeArray dna = _converterState.DocumentNodeArray;
            DocumentNode dnf = new DocumentNode(DocumentNodeType.dnFieldBegin);

            dnf.FormatState = new FormatState(formatState);
            dnf.IsPending = false;  // Field start mark should not impact other tags open/close behavior
            dnf.IsTerminated = true;
            dna.Push(dnf);
        }
        private void EnsureListAndListItem(FormatState formatState, DocumentNodeArray dna, MarkerList mlHave, MarkerList mlWant, int nMatch)
        {
            int nInsertAt;

            bool added = false;

            int nLists = mlHave.Count;
            int nLevel = mlWant.Count;

            // Close any open lists that don't match the ones we want.
            bool bInField = dna.FindUnmatched(DocumentNodeType.dnFieldBegin) >= 0;
            if (nLists > nMatch)
            {
                DocumentNode documentNodePara = dna.Pop();
                while (nLists > nMatch)
                {
                    int nOpen = dna.FindPending(DocumentNodeType.dnList);
                    if (nOpen >= 0)
                    {
                        dna.CloseAt(nOpen);

                        // Only coalesce if this is a top-level list.  Otherwise I want to get
                        // the full structure to use for margin fixups so I delay coalescing.
                        // No, don't coalesce since a later list may need to get merged with this one.
                        // if (!bInField && dna.FindPending(DocumentNodeType.dnList) < 0)
                        //    dna.CoalesceChildren(_converterState, nOpen);
                    }
                    nLists--;
                    mlHave.RemoveRange(mlHave.Count - 1, 1);
                }
                dna.Push(documentNodePara);
            }

            if (nLists < nLevel)
            {
                // Multiple immediately nested lists are handled poorly in Avalon and are usually an indication
                // of bad input from Word (or some other word processor).  Clip the number of lists we'll create here.
                if (nLevel != nLists + 1)
                {
                    // I'm going to truncate, but make the list I create here of the specific type at this level.
                    if (nLevel <= mlWant.Count)
                    {
                        mlWant[nLists] = mlWant[mlWant.Count - 1];
                    }
                    nLevel = nLists + 1;
                }

                // Ensure sufficient lists are open - this may be our first indication
                // Insert the list nodes right before the current paragraph
                nInsertAt = dna.Count - 1;

                while (nLists < nLevel)
                {
                    added = true;

                    DocumentNode dnList = new DocumentNode(DocumentNodeType.dnList);
                    DocumentNode dnLI = new DocumentNode(DocumentNodeType.dnListItem);

                    dna.InsertNode(nInsertAt, dnLI);
                    dna.InsertNode(nInsertAt, dnList);

                    // Set the list properties
                    MarkerListEntry mle = mlWant.EntryAt(nLists);
                    dnList.FormatState.Marker = mle.Marker;
                    dnList.FormatState.StartIndex = mle.StartIndexToUse;
                    dnList.FormatState.StartIndexDefault = mle.StartIndexDefault;
                    dnList.VirtualListLevel = mle.VirtualListLevel;
                    dnList.FormatState.ILS = mle.ILS;
                    nLists++;
                }
            }

            // Ensure listitem is open
            nInsertAt = dna.Count - 1;
            int nList = dna.FindPending(DocumentNodeType.dnList);
            if (nList >= 0)
            {
                int nLI = dna.FindPending(DocumentNodeType.dnListItem, nList);

                if (nLI >= 0 && !added && !formatState.IsContinue)
                {
                    DocumentNode documentNodePara = dna.Pop();
                    dna.CloseAt(nLI);
                    // Don't coalesce - I may need to do margin fixup.
                    // dna.CoalesceChildren(_converterState, nLI);
                    dna.Push(documentNodePara);

                    nLI = -1;
                    nInsertAt = dna.Count - 1;
                }
                if (nLI == -1)
                {
                    DocumentNode dnLI = new DocumentNode(DocumentNodeType.dnListItem);

                    dna.InsertNode(nInsertAt, dnLI);
                }
            }
        }
        internal void HandleTableNesting(FormatState formatState)
        {
            DocumentNodeArray dna = _converterState.DocumentNodeArray;

            // If we're in a throw-away destination, just return.
            if (!formatState.IsContentDestination || formatState.IsHidden)
            {
                return;
            }

            // Make sure proper number of tables are open to reflect this paragraphs nest level
            int nTables = dna.CountOpenNodes(DocumentNodeType.dnTable);
            int nLevel = (int)formatState.TableLevel;

            // If we're not in a table, end early
            if (nTables == nLevel && nTables == 0)
            {
                return;
            }

            if (nTables > nLevel)
            {
                DocumentNode dnPara = dna.Pop();

                bool bInField = dna.FindUnmatched(DocumentNodeType.dnFieldBegin) >= 0;
                while (nTables > nLevel)
                {

                    int nOpen = dna.FindPending(DocumentNodeType.dnTable);
                    if (nOpen >= 0)
                    {
                        dna.CloseAt(nOpen);
                        if (!bInField)
                        {
                            dna.CoalesceChildren(_converterState, nOpen);
                        }
                    }
                    nTables--;
                }
                dna.Push(dnPara);
            }
            else
            {
                // Before opening the table, let's close any open lists.  Word (RTF) allows somewhat
                // arbitrary interleaving (because there's no explicit nesting), but when converting to
                // XAML we have to choose an explicit nesting.  We never create a table *inside* a list, so
                // let's just terminate any open lists right now.
                if (nTables < nLevel)
                {
                    int nListAt = dna.FindPending(DocumentNodeType.dnList);
                    if (nListAt >= 0)
                    {
                        // I want the currently pending paragraph to be part of the table, not part of the list
                        // I'm going to close.  So I temporarily pop it off while closing off the list and then
                        // push it back on before inserting the table(s).
                        DocumentNode dnPara = dna.Pop();

                        while (nListAt >= 0)
                        {
                            dna.CloseAt(nListAt);
                            nListAt = dna.FindPending(DocumentNodeType.dnList);
                        }

                        dna.Push(dnPara);
                    }
                }

                // Ensure sufficient tables are open - this may be our first indication
                // Insert the table nodes right before the current paragraph.
                Debug.Assert(dna.Count > 0 && dna.EntryAt(dna.Count - 1).Type == DocumentNodeType.dnParagraph);

                int nInsertAt = dna.Count - 1;

                // Ensure row is open
                int nTable = dna.FindPending(DocumentNodeType.dnTable);
                if (nTable >= 0)
                {
                    int nRow = dna.FindPending(DocumentNodeType.dnRow, nTable);
                    if (nRow == -1)
                    {
                        DocumentNode dnRow = new DocumentNode(DocumentNodeType.dnRow);
                        dna.InsertNode(nInsertAt++, dnRow);
                        nRow = nInsertAt - 1;
                    }

                    int nCell = dna.FindPending(DocumentNodeType.dnCell, nRow);
                    if (nCell == -1)
                    {
                        DocumentNode dnCell = new DocumentNode(DocumentNodeType.dnCell);
                        dna.InsertNode(nInsertAt, dnCell);
                    }
                }

                nInsertAt = dna.Count - 1;
                while (nTables < nLevel)
                {
                    DocumentNode dnTable = new DocumentNode(DocumentNodeType.dnTable);
                    DocumentNode dnTableBody = new DocumentNode(DocumentNodeType.dnTableBody);
                    DocumentNode dnRow = new DocumentNode(DocumentNodeType.dnRow);
                    DocumentNode dnCell = new DocumentNode(DocumentNodeType.dnCell);

                    dna.InsertNode(nInsertAt, dnCell);
                    dna.InsertNode(nInsertAt, dnRow);
                    dna.InsertNode(nInsertAt, dnTableBody);
                    dna.InsertNode(nInsertAt, dnTable);

                    nTables++;
                }
            }

            dna.AssertTreeSemanticInvariants();
        }
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        internal void InheritFormatState(FormatState formatState)
        {
            _formatState = new FormatState(formatState);

            // Reset non-inherited properties
            _formatState.LI = 0;
            _formatState.RI = 0;
            _formatState.SB = 0;
            _formatState.SA = 0;
            _formatState.FI = 0;
            _formatState.Marker = MarkerStyle.MarkerNone;
            _formatState.CBPara = -1;
        }
        internal MarkerList GetMarkerStylesOfParagraph(MarkerList mlHave, FormatState fs, bool bMarkerPresent)
        {
            MarkerList mlWant = new MarkerList();
            long nVirtualListLevel = fs.ListLevel;
            long nStartIndexOverride = -1;

            // No list?
            if (nVirtualListLevel < 1)
            {
                return mlWant;
            }

            // Use currently open list styles for all levels below requested one
            for (int i = 0; i < mlHave.Count; i++)
                if (mlHave.EntryAt(i).VirtualListLevel < nVirtualListLevel || fs.IsContinue)
                {
                    MarkerListEntry mle = mlHave.EntryAt(i);
                    mlWant.AddEntry(mle.Marker, mle.ILS, -1, mle.StartIndexDefault, mle.VirtualListLevel);
                }
                else
                {
                    break;
                }

            // If I'm a continuation paragraph, I'm done.
            if (fs.IsContinue)
            {
                return mlWant;
            }

            // Now determine the list style for the list level I'm going to add.
            ListOverrideTable lot = _converterState.ListOverrideTable;
            ListOverride lo = lot.FindEntry((int)fs.ILS);
            if (lo != null)
            {
                ListLevelTable levels = lo.Levels;
                if (levels == null || levels.Count == 0)
                {
                    ListTableEntry lte = _converterState.ListTable.FindEntry(lo.ID);
                    if (lte != null)
                    {
                        levels = lte.Levels;
                    }

                    // Did the list override specify a start index?
                    if (lo.StartIndex > 0)
                    {
                        nStartIndexOverride = lo.StartIndex;
                    }
                }

                if (levels != null)
                {
                    ListLevel listLevel = levels.EntryAt((int)nVirtualListLevel - 1);
                    if (listLevel != null)
                    {
                        // If there was a marker present, we ignore the "Hidden" style in the list table.
                        MarkerStyle ms = listLevel.Marker;
                        if (ms == MarkerStyle.MarkerHidden && bMarkerPresent)
                        {
                            ms = MarkerStyle.MarkerBullet;
                        }

                        mlWant.AddEntry(ms, fs.ILS, nStartIndexOverride, listLevel.StartIndex, nVirtualListLevel);
                        return mlWant;
                    }
                }
            }

            // If there wasn't a list definition, use the marker type in the formatstate.
            mlWant.AddEntry(fs.Marker, fs.ILS, nStartIndexOverride, fs.StartIndex, nVirtualListLevel);
            return mlWant;
        }
        internal FormatState(FormatState formatState)
        {
            // Font settings
            Bold = formatState.Bold;
            Italic = formatState.Italic;
            Engrave = formatState.Engrave;
            Shadow = formatState.Shadow;
            SCaps = formatState.SCaps;
            Outline = formatState.Outline;
            Super = formatState.Super;
            Sub = formatState.Sub;
            SuperOffset = formatState.SuperOffset;
            FontSize = formatState.FontSize;
            Font = formatState.Font;
            CodePage = formatState.CodePage;
            CF = formatState.CF;
            CB = formatState.CB;
            DirChar = formatState.DirChar;
            UL = formatState.UL;
            Strike = formatState.Strike;
            Expand = formatState.Expand;
            Lang = formatState.Lang;
            LangFE = formatState.LangFE;
            LangCur = formatState.LangCur;
            FontSlot = formatState.FontSlot;

            // Para settings
            SB = formatState.SB;
            SA = formatState.SA;
            FI = formatState.FI;
            RI = formatState.RI;
            LI = formatState.LI;
            SL = formatState.SL;
            SLMult = formatState.SLMult;
            HAlign = formatState.HAlign;
            ILVL = formatState.ILVL;
            ITAP = formatState.ITAP;
            ILS = formatState.ILS;
            DirPara = formatState.DirPara;
            CFPara = formatState.CFPara;
            CBPara = formatState.CBPara;
            ParaShading = formatState.ParaShading;
            Marker = formatState.Marker;
            IsContinue = formatState.IsContinue;
            StartIndex = formatState.StartIndex;
            StartIndexDefault = formatState.StartIndexDefault;
            IsInTable = formatState.IsInTable;
            _pb = formatState.HasParaBorder ? new ParaBorder(formatState.ParaBorder) : null;

            // Row settings
            // For performance reasons, we don't make a full copy of the Row format information.  The implication
            // of this is that changes to row format data will propagate back up from nested scopes, which is not
            // according to the strict semantics.  But in practice, all new rows are explicitly cleared with the
            // \trowd keyword, which clears this, so this should be fine.
            RowFormat = formatState._rowFormat;

            // Other
            RtfDestination = formatState.RtfDestination;
            IsHidden = formatState.IsHidden;

            _stateSkip = formatState.UnicodeSkip;
        }
        internal void HandleListNesting(FormatState formatState)
        {
            DocumentNodeArray dna = _converterState.DocumentNodeArray;
            DocumentNode dnPara = dna.EntryAt(dna.Count - 1);
            bool bMarkerPresent = _converterState.IsMarkerPresent;

            // Test if we encountered list text
            if (_converterState.IsMarkerPresent)
            {
                _converterState.IsMarkerPresent = false;
            }

            // If we're in a throw-away destination, just return.
            if (!formatState.IsContentDestination || formatState.IsHidden)
            {
                return;
            }

            // Treat no marker text present as a continuation paragraph
            if (!bMarkerPresent && formatState.ListLevel > 0)
            {
                // Allocate a new one here so that this change doesn't propagate beyond here.
                formatState = new FormatState(formatState);

                // If the only thing making this look like a list is the ILVL property, just clear it.
                if (formatState.ILVL > 0 && formatState.ILS < 0)
                {
                    formatState.ILVL = 0;
                }
                else // otherwise treat this as a continuation paragraph.
                {
                    formatState.IsContinue = true;
                }
            }

            // Make sure proper number of lists are open to reflect this paragraphs nest level
            MarkerList mlHave = dna.GetOpenMarkerStyles();
            MarkerList mlWant = GetMarkerStylesOfParagraph(mlHave, formatState, bMarkerPresent);

            int nLists = mlHave.Count;
            int nLevel = mlWant.Count;

            // If we're not in a list end early
            if (nLists == nLevel && nLists == 0)
            {
                return;
            }

            // If we're not in a list and marked as a continuation, ignore this - anomaly.
            if (nLists == 0 && nLevel == 1 && formatState.IsContinue)
            {
                return;
            }

            // Propagate noticing that the specified text was empty.
            if (_converterState.IsMarkerWhiteSpace)
            {
                _converterState.IsMarkerWhiteSpace = false;
                if (nLevel > 0)
                {
                    MarkerListEntry entry = mlWant.EntryAt(nLevel - 1);
                    entry.Marker = MarkerStyle.MarkerHidden;
                }
            }

            // The ones we have are only "good" if the styles match what we want.
            int nMatch = GetMatchedMarkList(formatState, mlHave, mlWant);

            // If none match, we might do better by extending some previously open list.
            if (nMatch == 0)
            {
                MarkerList mlCouldHave = dna.GetLastMarkerStyles(mlHave, mlWant);
                MarkerList mlCouldWant = GetMarkerStylesOfParagraph(mlCouldHave, formatState, bMarkerPresent);
                nMatch = GetMatchedMarkList(formatState, mlCouldHave, mlCouldWant);

                // If I would re-open a previous list but close some set of them and then reopen another,
                // this is unlikely to be what the user intended.  Instead, don't extend the previous list.
                // See Windows OS Bugs: 1373731.
                if (nMatch < mlCouldHave.Count && mlCouldWant.Count > nMatch)
                {
                    nMatch = 0;
                }

                if (nMatch > 0)
                {
                    mlHave = mlCouldHave;
                    mlWant = mlCouldWant;
                    dna.OpenLastList();
                }
            }

            // Ensure list and listitem
            EnsureListAndListItem(formatState, dna, mlHave, mlWant, nMatch);

            // To get better results in XAML output, clear the FI for the first para in a list item.
            if (dna.Count > 1 && dna.EntryAt(dna.Count - 2).Type == DocumentNodeType.dnListItem)
            {
                Debug.Assert(!dnPara.IsTerminated);
                dnPara.FormatState.FI = 0;
            }

            dna.AssertTreeSemanticInvariants();
        }
        internal bool IsEqual(FormatState formatState)
        {
            return
                // Font Settings
                   Bold == formatState.Bold
                && Italic == formatState.Italic
                && Engrave == formatState.Engrave
                && Shadow == formatState.Shadow
                && SCaps == formatState.SCaps
                && Outline == formatState.Outline
                && Super == formatState.Super
                && Sub == formatState.Sub
                && SuperOffset == formatState.SuperOffset
                && FontSize == formatState.FontSize
                && Font == formatState.Font
                && CodePage == formatState.CodePage
                && CF == formatState.CF
                && CB == formatState.CB
                && DirChar == formatState.DirChar
                && UL == formatState.UL
                && Strike == formatState.Strike
                && Expand == formatState.Expand
                && Lang == formatState.Lang
                && LangFE == formatState.LangFE
                && LangCur == formatState.LangCur
                && FontSlot == formatState.FontSlot

                // Para settings
                && SB == formatState.SB
                && SA == formatState.SA
                && FI == formatState.FI
                && RI == formatState.RI
                && LI == formatState.LI
                && HAlign == formatState.HAlign
                && ILVL == formatState.ILVL
                && ITAP == formatState.ITAP
                && ILS == formatState.ILS
                && DirPara == formatState.DirPara
                && CFPara == formatState.CFPara
                && CBPara == formatState.CBPara
                && ParaShading == formatState.ParaShading
                && Marker == formatState.Marker
                && IsContinue == formatState.IsContinue
                && StartIndex == formatState.StartIndex
                && StartIndexDefault == formatState.StartIndexDefault
                && SL == formatState.SL
                && SLMult == formatState.SLMult
                && IsInTable == formatState.IsInTable

                // Don't include para borders in this test

                // Row Settings
                // Don't include row settings in this test.

                // Other
                && RtfDestination == formatState.RtfDestination
                && IsHidden == formatState.IsHidden
                && UnicodeSkip == formatState.UnicodeSkip;
        }
        internal void HandleCodePageTokens(RtfToken token, FormatState formatState)
        {
            switch (token.RtfControlWordInfo.Control)
            {
                case RtfControlWord.Ctrl_ANSI:
                    // ANSI apparently means specifically 1252, not ACP.  That makes a lot more sense...
                    //_converterState.CodePage = CultureInfo.CurrentCulture.TextInfo.ANSICodePage;
                    _converterState.CodePage = 1252;
                    _lexer.CodePage = _converterState.CodePage;
                    break;
                case RtfControlWord.Ctrl_MAC:
                    _converterState.CodePage = 10000;
                    _lexer.CodePage = _converterState.CodePage;
                    break;
                case RtfControlWord.Ctrl_PC:
                    _converterState.CodePage = 437;
                    _lexer.CodePage = _converterState.CodePage;
                    break;
                case RtfControlWord.Ctrl_PCA:
                    _converterState.CodePage = 850;
                    _lexer.CodePage = _converterState.CodePage;
                    break;
                case RtfControlWord.Ctrl_UPR:
                    // We discard this ansi representation - \ud will then switch back to current.
                    formatState.RtfDestination = RtfDestination.DestUPR;
                    break;
                case RtfControlWord.Ctrl_U:
                    {
                        char[] unicodeChar = new char[1];

                        unicodeChar[0] = (char)token.Parameter;
                        ProcessText(new string(unicodeChar));
                    }
                    break;
                case RtfControlWord.Ctrl_UD:
                    {
                        // We are parsing: {\upr ansi stuff{\*\ud unicode stuff }}
                        // When we encountered the UPR we set state to a throwaway destination (DestUPR).
                        // The nested group pushed a new format state but that now has DestUnknown because of this.
                        // Now that we encountered the \ud destination, lets push back the original destination.
                        FormatState previous = _converterState.PreviousTopFormatState(1);
                        FormatState previousPrevious = _converterState.PreviousTopFormatState(2);
                        if (previous != null && previousPrevious != null)
                        {
                            if (formatState.RtfDestination == RtfDestination.DestUPR && previous.RtfDestination == RtfDestination.DestUnknown)
                            {
                                formatState.RtfDestination = previousPrevious.RtfDestination;
                            }
                        }
                    }
                    break;
                case RtfControlWord.Ctrl_UC:
                    formatState.UnicodeSkip = (int)token.Parameter;
                    break;
            }
        }
 internal void HandleBinControl(RtfToken token, FormatState formatState)
 {
     if (token.Parameter > 0)
     {
         if (formatState.RtfDestination == RtfDestination.DestPicture)
         {
             formatState.IsImageDataBinary = true;
         }
         else
         {
             _lexer.AdvanceForBinary((int)token.Parameter);
         }
     }
 }
        internal void HandleNormalText(string text, FormatState formatState)
        {
            // Normal CRLF's are eaten by the RTF lexer.  Any ones that have slipped through here
            // were either escaped or hex-encoded and should be treated as a linebreak.
            int nStart = 0;
            while (nStart < text.Length)
            {
                int nEnd = nStart;
                while (nEnd < text.Length)
                {
                    if (text[nEnd] == 0x0d || text[nEnd] == 0x0a)
                    {
                        break;
                    }
                    nEnd++;
                }

                // Handle text before newline
                if (nStart == 0 && nEnd == text.Length)
                {
                    HandleNormalTextRaw(text, formatState);
                }
                else if (nEnd > nStart)
                {
                    string subtext = text.Substring(nStart, nEnd - nStart);
                    HandleNormalTextRaw(subtext, formatState);
                }

                // Handle newlines
                while (nEnd < text.Length && (text[nEnd] == 0x0d || text[nEnd] == 0x0a))
                {
                    ProcessNormalHardLine(formatState);

                    if (nEnd + 1 < text.Length && text[nEnd] == 0x0d && text[nEnd] == 0x0a)
                    {
                        nEnd += 2;
                    }
                    else
                    {
                        nEnd += 1;
                    }
                }

                nStart = nEnd;
            }
        }
        internal void WrapPendingInlineInParagraph(RtfToken token, FormatState formatState)
        {
            // Ignore \par in other destinations
            if (!formatState.IsContentDestination || formatState.IsHidden)
            {
                return;
            }

            // Only treat \page as \par if there is already some inline content.  In normal cases,
            // (e.g. Word output) a page break comes between paragraphs and we don't want to emit
            // anything extra in that case.
            DocumentNodeArray dna = _converterState.DocumentNodeArray;
            DocumentNode dn;

            // Insert the paragraph before any text or inline nodes at the top of the stack.
            int nNoOpValue = dna.Count;
            int nInsertAt = dna.Count;    // Default insertion location
            for (; nInsertAt > 0; nInsertAt--)
            {
                dn = dna.EntryAt(nInsertAt - 1);
                if (!dn.IsInline || dn.ClosedParent != null || !dn.IsMatched)
                {
                    break;
                }

                // If we only have listtext on the stack, don't force a para.
                else if (dn.Type == DocumentNodeType.dnListText && !dn.IsPending
                         && nInsertAt + dn.ChildCount == dna.Count)
                {
                    nNoOpValue = nInsertAt - 1;
                }
            }

            // If there are no inline nodes, don't generate extra content.
            if (nInsertAt == nNoOpValue)
            {
                return;
            }

            // Otherwise, just treat as paragraph mark
            HandlePara(token, formatState);
        }
        internal void HandleNormalTextRaw(string text, FormatState formatState)
        {
            DocumentNodeArray dna = _converterState.DocumentNodeArray;
            DocumentNode dnTop = dna.Top;

            // See if I can just append the text content if the format is the same.
            if (dnTop != null && (dnTop.Type == DocumentNodeType.dnText))
            {
                // If the format is not equal, close this text element and we'll open a new one.
                if (!dnTop.FormatState.IsEqual(formatState))
                {
                    dna.CloseAt(dna.Count - 1);
                    dnTop = null;
                }
            }

            // OK, create a text node if necessary
            if (dnTop == null || dnTop.Type != DocumentNodeType.dnText)
            {
                dnTop = new DocumentNode(DocumentNodeType.dnText);
                dnTop.FormatState = new FormatState(formatState);
                dna.Push(dnTop);
            }

            Debug.Assert(!dnTop.IsTerminated);
            dnTop.AppendXamlEncoded(text);
            dnTop.IsPending = false;
        }
        internal void HandleParagraphFromText(FormatState formatState)
        {
            DocumentNodeArray dna = _converterState.DocumentNodeArray;
            DocumentNode dn;

            // Insert the paragraph before any text or inline nodes at the top of the stack.
            int nInsertAt = dna.Count;    // Default insertion location
            for (; nInsertAt > 0; nInsertAt--)
            {
                dn = dna.EntryAt(nInsertAt - 1);
                if (!dn.IsInline
                    || (dn.ClosedParent != null && !dn.ClosedParent.IsInline)
                    || !dn.IsMatched)
                {
                    break;
                }
            }

            dn = new DocumentNode(DocumentNodeType.dnParagraph);
            dn.FormatState = new FormatState(formatState);
            dn.ConstrainFontPropagation(formatState);
            dna.InsertNode(nInsertAt, dn);

            // Now close immediately.
            dna.CloseAt(nInsertAt);
            dna.CoalesceOnlyChildren(_converterState, nInsertAt);
        }
        internal void ProcessNormalHardLine(FormatState formatState)
        {
            // Close out pending text nodes
            DocumentNodeArray dna = _converterState.DocumentNodeArray;

            if (dna.TestTop(DocumentNodeType.dnText))
            {
                dna.CloseAt(dna.Count - 1);
            }

            DocumentNode documentNode = new DocumentNode(DocumentNodeType.dnLineBreak);
            documentNode.FormatState = new FormatState(formatState);
            dna.Push(documentNode);
            dna.CloseAt(dna.Count - 1);
            dna.CoalesceChildren(_converterState, dna.Count - 1);
        }
Esempio n. 35
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        /// <summary>
        ///
        /// </summary>
        /// <param name="token"></param>
        /// <param name="formatState"></param>
        /// <returns></returns>
        internal RtfToXamlError Next(RtfToken token, FormatState formatState)
        {
            RtfToXamlError rtfToXamlError = RtfToXamlError.None;

            _rtfLastIndex = _rtfIndex;

            token.Empty();

            if (_rtfIndex >= _rtfBytes.Length)
            {
                token.Type = RtfTokenType.TokenEOF;
                return(rtfToXamlError);
            }

            int  rtfStartIndex = _rtfIndex;
            byte tokenChar     = _rtfBytes[_rtfIndex++];

            switch (tokenChar)
            {
            // GroupStart
            case (byte)'{':
                token.Type = RtfTokenType.TokenGroupStart;
                break;

            // GroupEnd
            case (byte)'}':
                token.Type = RtfTokenType.TokenGroupEnd;
                break;

            // Control Word
            case (byte)'\r':
            case (byte)'\n':
                token.Type = RtfTokenType.TokenNewline;
                break;

            case (byte)0:
                token.Type = RtfTokenType.TokenNullChar;
                break;

            case (byte)'\\':
                // Input ends with control sequence
                if (_rtfIndex >= _rtfBytes.Length)
                {
                    token.Type = RtfTokenType.TokenInvalid;
                }
                // Normal control character
                else
                {
                    if (IsControlCharValid(CurByte))
                    {
                        int controlStartIndex = _rtfIndex;

                        // Set _rtfIndex to get actual control
                        SetRtfIndex(token, controlStartIndex);

                        // Also provide actual control text - useful for unknown controls
                        token.Text = CurrentEncoding.GetString(_rtfBytes, controlStartIndex - 1, _rtfIndex - rtfStartIndex);
                    }
                    // Hex character
                    else if (CurByte == (byte)'\'')
                    {
                        _rtfIndex--;
                        return(NextText(token));
                    }
                    // Explicit destination
                    else if (CurByte == '*')
                    {
                        _rtfIndex++;
                        token.Type = RtfTokenType.TokenDestination;
                    }
                    // Quoted control character (be generous) - should be limited to "'-*;\_{|}~"
                    else
                    {
                        token.Type = RtfTokenType.TokenTextSymbol;
                        token.Text = CurrentEncoding.GetString(_rtfBytes, _rtfIndex, 1);

                        _rtfIndex++;
                    }
                }

                break;

            // Text or Picture data
            default:
                _rtfIndex--;

                if (formatState != null && formatState.RtfDestination == RtfDestination.DestPicture)
                {
                    token.Type = RtfTokenType.TokenPictureData;
                    break;
                }
                else
                {
                    return(NextText(token));
                }
            }

            return(rtfToXamlError);
        }
Esempio n. 36
0
 // Token: 0x060032DF RID: 13023 RVA: 0x000E5564 File Offset: 0x000E3764
 internal bool IsEqual(FormatState formatState)
 {
     return(this.Bold == formatState.Bold && this.Italic == formatState.Italic && this.Engrave == formatState.Engrave && this.Shadow == formatState.Shadow && this.SCaps == formatState.SCaps && this.Outline == formatState.Outline && this.Super == formatState.Super && this.Sub == formatState.Sub && this.SuperOffset == formatState.SuperOffset && this.FontSize == formatState.FontSize && this.Font == formatState.Font && this.CodePage == formatState.CodePage && this.CF == formatState.CF && this.CB == formatState.CB && this.DirChar == formatState.DirChar && this.UL == formatState.UL && this.Strike == formatState.Strike && this.Expand == formatState.Expand && this.Lang == formatState.Lang && this.LangFE == formatState.LangFE && this.LangCur == formatState.LangCur && this.FontSlot == formatState.FontSlot && this.SB == formatState.SB && this.SA == formatState.SA && this.FI == formatState.FI && this.RI == formatState.RI && this.LI == formatState.LI && this.HAlign == formatState.HAlign && this.ILVL == formatState.ILVL && this.ITAP == formatState.ITAP && this.ILS == formatState.ILS && this.DirPara == formatState.DirPara && this.CFPara == formatState.CFPara && this.CBPara == formatState.CBPara && this.ParaShading == formatState.ParaShading && this.Marker == formatState.Marker && this.IsContinue == formatState.IsContinue && this.StartIndex == formatState.StartIndex && this.StartIndexDefault == formatState.StartIndexDefault && this.SL == formatState.SL && this.SLMult == formatState.SLMult && this.IsInTable == formatState.IsInTable && this.RtfDestination == formatState.RtfDestination && this.IsHidden == formatState.IsHidden && this.UnicodeSkip == formatState.UnicodeSkip);
 }