// Token: 0x060032B7 RID: 12983 RVA: 0x000E4290 File Offset: 0x000E2490
        private void SetRtfIndex(RtfToken token, int controlStartIndex)
        {
            while (this._rtfIndex < this._rtfBytes.Length && this.IsControlCharValid(this.CurByte))
            {
                this._rtfIndex++;
            }
            int    num     = this._rtfIndex - controlStartIndex;
            string @string = this.CurrentEncoding.GetString(this._rtfBytes, controlStartIndex, num);

            if (num > 32)
            {
                token.Type = RtfTokenType.TokenInvalid;
                return;
            }
            token.Type = RtfTokenType.TokenControl;
            token.RtfControlWordInfo = RtfToXamlLexer.RtfControlWordLookup(@string);
            if (this._rtfIndex < this._rtfBytes.Length)
            {
                if (this.CurByte == 32)
                {
                    this._rtfIndex++;
                    return;
                }
                if (this.IsParameterStart(this.CurByte))
                {
                    bool flag = false;
                    if (this.CurByte == 45)
                    {
                        flag = true;
                        this._rtfIndex++;
                    }
                    long num2     = 0L;
                    int  rtfIndex = this._rtfIndex;
                    while (this._rtfIndex < this._rtfBytes.Length && this.IsParameterFollow(this.CurByte))
                    {
                        num2 = num2 * 10L + (long)(this.CurByte - 48);
                        this._rtfIndex++;
                    }
                    int num3 = this._rtfIndex - rtfIndex;
                    if (this._rtfIndex < this._rtfBytes.Length && this.CurByte == 32)
                    {
                        this._rtfIndex++;
                    }
                    if (flag)
                    {
                        num2 = -num2;
                    }
                    if (num3 > 10)
                    {
                        token.Type = RtfTokenType.TokenInvalid;
                        return;
                    }
                    token.Parameter = num2;
                }
            }
        }
        // Token: 0x060032AE RID: 12974 RVA: 0x000E3E88 File Offset: 0x000E2088
        internal RtfToXamlError AdvanceForUnicode(long nSkip)
        {
            RtfToXamlError rtfToXamlError = RtfToXamlError.None;
            RtfToken       rtfToken       = new RtfToken();

            while (nSkip > 0L && rtfToXamlError == RtfToXamlError.None)
            {
                rtfToXamlError = this.Next(rtfToken, null);
                if (rtfToXamlError != RtfToXamlError.None)
                {
                    break;
                }
                switch (rtfToken.Type)
                {
                default:
                    this.Backup();
                    nSkip = 0L;
                    break;

                case RtfTokenType.TokenText:
                {
                    int rtfIndex = this._rtfIndex;
                    this.Backup();
                    while (nSkip > 0L && this._rtfIndex < rtfIndex)
                    {
                        if (this.CurByte == 92)
                        {
                            this._rtfIndex += 4;
                        }
                        else
                        {
                            this._rtfIndex++;
                        }
                        nSkip -= 1L;
                    }
                    break;
                }

                case RtfTokenType.TokenNewline:
                case RtfTokenType.TokenNullChar:
                    break;

                case RtfTokenType.TokenControl:
                    if (rtfToken.RtfControlWordInfo != null && rtfToken.RtfControlWordInfo.Control == RtfControlWord.Ctrl_BIN)
                    {
                        this.AdvanceForBinary((int)rtfToken.Parameter);
                    }
                    nSkip -= 1L;
                    break;
                }
            }
            return(rtfToXamlError);
        }
예제 #3
0
        internal RtfToXamlError AdvanceForUnicode(long nSkip)
        {
            RtfToXamlError rtfToXamlError = RtfToXamlError.None;

            // Advancing for text is a little tricky
            RtfToken token = new RtfToken();

            while (nSkip > 0 && rtfToXamlError == RtfToXamlError.None)
            {
                rtfToXamlError = Next(token, /*formatState:*/ null);

                if (rtfToXamlError != RtfToXamlError.None)
                {
                    break;
                }

                switch (token.Type)
                {
                default:
                case RtfTokenType.TokenGroupStart:
                case RtfTokenType.TokenGroupEnd:
                case RtfTokenType.TokenInvalid:
                case RtfTokenType.TokenEOF:
                case RtfTokenType.TokenDestination:
                    Backup();
                    nSkip = 0;
                    break;

                case RtfTokenType.TokenControl:
                    if (token.RtfControlWordInfo != null && token.RtfControlWordInfo.Control == RtfControlWord.Ctrl_BIN)
                    {
                        AdvanceForBinary((int)token.Parameter);
                    }
                    nSkip--;
                    break;

                case RtfTokenType.TokenNewline:
                    // Newlines don't count for skipping purposes
                    break;

                case RtfTokenType.TokenNullChar:
                    // Null chars don't count for skipping purposes
                    break;

                case RtfTokenType.TokenText:
                    // We need to skip *bytes*, considering hex-encoded control words as a single byte.
                    // Since Next() returned TokenText, we know that we can safely assume that the next
                    // sequence of bytes is either simple text or hex-encoded bytes.
                    int nEndTextIndex = _rtfIndex;
                    Backup();
                    while (nSkip > 0 && _rtfIndex < nEndTextIndex)
                    {
                        if (CurByte == '\\')
                        {
                            _rtfIndex += 4;
                        }
                        else
                        {
                            _rtfIndex++;
                        }
                        nSkip--;
                    }
                    break;
                }
            }

            return(rtfToXamlError);
        }
 internal void HandlePage(RtfToken token, FormatState formatState)
 {
     WrapPendingInlineInParagraph(token, formatState);
 }
        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);
        }
        internal void ProcessTextSymbol(RtfToken token)
        {
            // Quoted control character (be generous) - should be limited to "'-*;\_{|}~"

            if (token.Text.Length == 0)
            {
                return;
            }

            // Set token text with the quoted control character
            SetTokenTextWithControlCharacter(token);

            switch (_converterState.TopFormatState.RtfDestination)
            {
                case RtfDestination.DestNormal:
                case RtfDestination.DestFieldResult:
                case RtfDestination.DestShapeResult:
                case RtfDestination.DestListText:
                    HandleNormalText(token.Text, _converterState.TopFormatState);
                    break;
                case RtfDestination.DestFontTable:
                    ProcessFontTableText(token);
                    break;
                case RtfDestination.DestColorTable:
                    ProcessColorTableText(token);
                    break;
                case RtfDestination.DestField:
                case RtfDestination.DestFieldInstruction:
                case RtfDestination.DestFieldPrivate:
                    ProcessFieldText(token);
                    break;
            }
        }
        internal void HandleControl(RtfToken token, RtfControlWordInfo controlWordInfo)
        {
            FormatState formatState = _converterState.TopFormatState;

            if (formatState == null)
            {
                return;
            }

            switch (controlWordInfo.Control)
            {
                case RtfControlWord.Ctrl_V:
                    formatState.IsHidden = token.ToggleValue > 0;
                    break;
                case RtfControlWord.Ctrl_DELETED:
                    formatState.IsHidden = true;
                    break;
                case RtfControlWord.Ctrl_B:
                    formatState.Bold = token.ToggleValue > 0;
                    break;
                case RtfControlWord.Ctrl_I:
                    formatState.Italic = token.ToggleValue > 0;
                    break;
                case RtfControlWord.Ctrl_IMPR:
                    formatState.Engrave = token.ToggleValue > 0;
                    break;
                case RtfControlWord.Ctrl_OUTL:
                    formatState.Outline = token.ToggleValue > 0;
                    break;
                case RtfControlWord.Ctrl_SHAD:
                    formatState.Shadow = token.ToggleValue > 0;
                    break;
                case RtfControlWord.Ctrl_SCAPS:
                    formatState.SCaps = token.ToggleValue > 0;
                    break;
                case RtfControlWord.Ctrl_FS:
                    if (Validators.IsValidFontSize(token.Parameter))
                        formatState.FontSize = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_EXPND:
                case RtfControlWord.Ctrl_EXPNDTW:
                    formatState.Expand = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_F:
                    if (token.HasParameter)
                        if (formatState.RtfDestination == RtfDestination.DestFontTable)
                        {
                            _converterState.FontTable.DefineEntry((int)token.Parameter);
                        }
                        else
                        {
                            SelectFont(token.Parameter);

                            // Setting font also sets current language in effect
                            if (formatState.FontSlot == FontSlot.DBCH)
                            {
                                if (formatState.LangFE > 0)
                                {
                                    formatState.LangCur = formatState.LangFE;
                                }
                                else if (_converterState.DefaultLangFE > 0)
                                {
                                    formatState.LangCur = _converterState.DefaultLangFE;
                                }
                            }
                            else
                            {
                                if (formatState.Lang > 0)
                                {
                                    formatState.LangCur = formatState.Lang;
                                }
                                else if (_converterState.DefaultLang > 0)
                                {
                                    formatState.LangCur = _converterState.DefaultLang;
                                }
                            }
                        }

                    break;
                case RtfControlWord.Ctrl_DBCH:
                    formatState.FontSlot = FontSlot.DBCH;
                    break;
                case RtfControlWord.Ctrl_LOCH:
                    formatState.FontSlot = FontSlot.LOCH;
                    break;
                case RtfControlWord.Ctrl_HICH:
                    formatState.FontSlot = FontSlot.HICH;
                    break;
                case RtfControlWord.Ctrl_LANG:
                    formatState.Lang = token.Parameter;
                    formatState.LangCur = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_LANGFE:
                    formatState.LangFE = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_DEFLANG:
                    _converterState.DefaultLang = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_DEFLANGFE:
                    _converterState.DefaultLangFE = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_DEFF:
                    _converterState.DefaultFont = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_FNAME:
                    {
                        FormatState previousFormatState = _converterState.PreviousTopFormatState(1);
                        if (previousFormatState.RtfDestination == RtfDestination.DestFontTable)
                        {
                            formatState.RtfDestination = RtfDestination.DestFontName;
                            FontTableEntry entry = _converterState.FontTable.CurrentEntry;
                            if (entry != null)
                            {
                                entry.Name = null;
                            }
                        }
                    }
                    break;
                case RtfControlWord.Ctrl_FCHARSET:
                    if (formatState.RtfDestination == RtfDestination.DestFontTable)
                    {
                        HandleFontTableTokens(token);
                    }
                    break;
                case RtfControlWord.Ctrl_HIGHLIGHT:
                    formatState.CB = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_CB:
                    formatState.CB = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_CF:
                    formatState.CF = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_SUB:
                    formatState.Sub = token.FlagValue;
                    if (formatState.Sub)
                    {
                        formatState.Super = false;
                    }
                    break;
                case RtfControlWord.Ctrl_SUPER:
                    formatState.Super = token.FlagValue;
                    if (formatState.Super)
                    {
                        formatState.Sub = false;
                    }
                    break;
                case RtfControlWord.Ctrl_NOSUPERSUB:
                    formatState.Sub = false;
                    formatState.Super = false;

                    formatState.SuperOffset = 0;
                    break;
                case RtfControlWord.Ctrl_UP:
                    formatState.SuperOffset = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_ULC:
                    // NB: underline color not implemented
                    break;
                case RtfControlWord.Ctrl_UL:
                case RtfControlWord.Ctrl_ULD:
                case RtfControlWord.Ctrl_ULDASH:
                case RtfControlWord.Ctrl_ULDASHD:
                case RtfControlWord.Ctrl_ULDASHDD:
                case RtfControlWord.Ctrl_ULDB:
                case RtfControlWord.Ctrl_ULHAIR:
                case RtfControlWord.Ctrl_ULHWAVE:
                case RtfControlWord.Ctrl_ULLDASH:
                case RtfControlWord.Ctrl_ULTH:
                case RtfControlWord.Ctrl_ULTHD:
                case RtfControlWord.Ctrl_ULTHDASH:
                case RtfControlWord.Ctrl_ULTHDASHD:
                case RtfControlWord.Ctrl_ULTHDASHDD:
                case RtfControlWord.Ctrl_ULTHLDASH:
                case RtfControlWord.Ctrl_ULULDBWAVE:
                case RtfControlWord.Ctrl_ULWAVE:
                case RtfControlWord.Ctrl_ULW:
                    formatState.UL = (token.ToggleValue > 0 ? ULState.ULNormal : ULState.ULNone);
                    break;
                case RtfControlWord.Ctrl_ULNONE:
                    formatState.UL = ULState.ULNone;
                    break;
                case RtfControlWord.Ctrl_STRIKE:
                    formatState.Strike = token.ToggleValue > 0 ? StrikeState.StrikeNormal : StrikeState.StrikeNone;
                    break;
                case RtfControlWord.Ctrl_STRIKED:
                    formatState.Strike = token.ToggleValue > 0 ? StrikeState.StrikeDouble : StrikeState.StrikeNone;
                    break;
                case RtfControlWord.Ctrl_PLAIN:
                    formatState.SetCharDefaults();
                    if (_converterState.DefaultFont >= 0)
                    {
                        SelectFont(_converterState.DefaultFont);
                    }
                    break;

                // Paragraph settings
                case RtfControlWord.Ctrl_PARD:
                    formatState.SetParaDefaults();
                    break;
                case RtfControlWord.Ctrl_SB:
                    formatState.SB = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_SA:
                    formatState.SA = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_FI:
                    // Word first indent(\fiN) and Avalon TextIndent concept is the different.
                    // So we ignore the negative first indent safely which can make the content invisible.
                    // Word: \fi-200        -200    0   200
                    //                              abc
                    //                                  xyz
                    // Word: \fi200         -200    0   200
                    //                                  abc
                    //                              xyz
                    if (token.Parameter > 0)
                    {
                        formatState.FI = token.Parameter;
                    }
                    break;
                case RtfControlWord.Ctrl_LIN:
                    // We ignore \lin and do RTL fixup on margins outselves.
                    // formatState.LI = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_LI:
                    formatState.LI = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_RIN:
                    // We ignore \rin and do RTL fixup on margins outselves.
                    // formatState.RI = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_RI:
                    formatState.RI = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_QC:
                    formatState.HAlign = HAlign.AlignCenter;
                    break;
                case RtfControlWord.Ctrl_QJ:
                    formatState.HAlign = HAlign.AlignJustify;
                    break;
                case RtfControlWord.Ctrl_QL:
                    formatState.HAlign = HAlign.AlignLeft;
                    break;
                case RtfControlWord.Ctrl_QR:
                    formatState.HAlign = HAlign.AlignRight;
                    break;
                case RtfControlWord.Ctrl_CFPAT:
                    formatState.CFPara = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_SHADING:
                    // Shading of the CFPAT color, in 100's of a percent.
                    formatState.ParaShading = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_CBPAT:
                    formatState.CBPara = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_SL:
                    formatState.SL = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_SLMULT:
                    formatState.SLMult = token.ToggleValue > 0;
                    break;

                // Special text
                case RtfControlWord.Ctrl_LINE:
                    ProcessHardLine(token, formatState);
                    break;

                // LTR-RTL stuff
                case RtfControlWord.Ctrl_LTRCH:
                    formatState.DirChar = DirState.DirLTR;
                    break;
                case RtfControlWord.Ctrl_LTRPAR:
                case RtfControlWord.Ctrl_LTRDOC:
                case RtfControlWord.Ctrl_LTRSECT:
                    formatState.DirPara = DirState.DirLTR;
                    break;
                case RtfControlWord.Ctrl_RTLCH:
                    formatState.DirChar = DirState.DirRTL;
                    break;
                case RtfControlWord.Ctrl_RTLPAR:
                case RtfControlWord.Ctrl_RTLDOC:
                case RtfControlWord.Ctrl_RTLSECT:
                    formatState.DirPara = DirState.DirRTL;
                    // RTF defaults paragraph alignment to left for both RTL and LTR paragraphs, but
                    // Avalon switches the default.  Hard-code the alignment here when dealing with RTL
                    // paragraphs so that the distinction doesn't result in different defaults.
                    if (formatState.HAlign == HAlign.AlignDefault)
                    {
                        formatState.HAlign = HAlign.AlignLeft;
                    }
                    break;
                case RtfControlWord.Ctrl_LTRMARK:
                    ProcessText(new string('\x200e', 1));
                    break;
                case RtfControlWord.Ctrl_RTLMARK:
                    ProcessText(new string('\x200f', 1));
                    break;

                // Structure output
                case RtfControlWord.Ctrl_PAR:
                case RtfControlWord.Ctrl_SECT:
                    HandlePara(token, formatState);
                    break;

                case RtfControlWord.Ctrl_PAGE:
                    HandlePage(token, formatState);
                    break;

                // Table Tokens
                case RtfControlWord.Ctrl_CELL:
                case RtfControlWord.Ctrl_NESTCELL:
                case RtfControlWord.Ctrl_ROW:
                case RtfControlWord.Ctrl_TROWD:
                case RtfControlWord.Ctrl_NESTROW:
                case RtfControlWord.Ctrl_NESTTABLEPROPS:
                    HandleTableTokens(token, formatState);
                    break;

                // Table property tokens
                case RtfControlWord.Ctrl_TRGAPH:
                case RtfControlWord.Ctrl_TRLEFT:
                case RtfControlWord.Ctrl_TRQC:
                case RtfControlWord.Ctrl_TRQL:
                case RtfControlWord.Ctrl_TRQR:
                case RtfControlWord.Ctrl_TRPADDL:
                case RtfControlWord.Ctrl_TRPADDR:
                case RtfControlWord.Ctrl_TRPADDB:
                case RtfControlWord.Ctrl_TRPADDT:
                case RtfControlWord.Ctrl_TRPADDFL:
                case RtfControlWord.Ctrl_TRPADDFT:
                case RtfControlWord.Ctrl_TRPADDFB:
                case RtfControlWord.Ctrl_TRPADDFR:
                case RtfControlWord.Ctrl_TRFTSWIDTH:
                case RtfControlWord.Ctrl_TRFTSWIDTHB:
                case RtfControlWord.Ctrl_TRFTSWIDTHA:
                case RtfControlWord.Ctrl_TRWWIDTH:
                case RtfControlWord.Ctrl_TRWWIDTHB:
                case RtfControlWord.Ctrl_TRWWIDTHA:
                case RtfControlWord.Ctrl_TRAUTOFIT:
                case RtfControlWord.Ctrl_CLWWIDTH:
                case RtfControlWord.Ctrl_CLFTSWIDTH:
                case RtfControlWord.Ctrl_TRBRDRT:
                case RtfControlWord.Ctrl_TRBRDRB:
                case RtfControlWord.Ctrl_TRBRDRR:
                case RtfControlWord.Ctrl_TRBRDRL:
                case RtfControlWord.Ctrl_TRBRDRV:
                case RtfControlWord.Ctrl_TRBRDRH:
                case RtfControlWord.Ctrl_CLVERTALT:
                case RtfControlWord.Ctrl_CLVERTALB:
                case RtfControlWord.Ctrl_CLVERTALC:
                case RtfControlWord.Ctrl_CLSHDRAWNIL:
                case RtfControlWord.Ctrl_CLSHDNG:
                case RtfControlWord.Ctrl_CLBRDRB:
                case RtfControlWord.Ctrl_CLBRDRR:
                case RtfControlWord.Ctrl_CLBRDRT:
                case RtfControlWord.Ctrl_CLBRDRL:
                case RtfControlWord.Ctrl_CLCBPAT:
                case RtfControlWord.Ctrl_CLCFPAT:
                case RtfControlWord.Ctrl_CLPADL:
                case RtfControlWord.Ctrl_CLPADFL:
                case RtfControlWord.Ctrl_CLPADR:
                case RtfControlWord.Ctrl_CLPADFR:
                case RtfControlWord.Ctrl_CLPADT:
                case RtfControlWord.Ctrl_CLPADFT:
                case RtfControlWord.Ctrl_CLPADB:
                case RtfControlWord.Ctrl_CLPADFB:
                case RtfControlWord.Ctrl_CELLX:
                case RtfControlWord.Ctrl_BRDRART:
                case RtfControlWord.Ctrl_BRDRB:
                case RtfControlWord.Ctrl_BRDRNIL:
                case RtfControlWord.Ctrl_BRDRNONE:
                case RtfControlWord.Ctrl_BRDRTBL:
                case RtfControlWord.Ctrl_BRDRBAR:
                case RtfControlWord.Ctrl_BRDRBTW:
                case RtfControlWord.Ctrl_BRDRCF:
                case RtfControlWord.Ctrl_BRDRDASH:
                case RtfControlWord.Ctrl_BRDRDASHD:
                case RtfControlWord.Ctrl_BRDRDASHDD:
                case RtfControlWord.Ctrl_BRDRDASHDOTSTR:
                case RtfControlWord.Ctrl_BRDRDASHSM:
                case RtfControlWord.Ctrl_BRDRDB:
                case RtfControlWord.Ctrl_BRDRDOT:
                case RtfControlWord.Ctrl_BRDREMBOSS:
                case RtfControlWord.Ctrl_BRDRENGRAVE:
                case RtfControlWord.Ctrl_BRDRFRAME:
                case RtfControlWord.Ctrl_BRDRHAIR:
                case RtfControlWord.Ctrl_BRDRINSET:
                case RtfControlWord.Ctrl_BRDRL:
                case RtfControlWord.Ctrl_BRDROUTSET:
                case RtfControlWord.Ctrl_BRDRR:
                case RtfControlWord.Ctrl_BRDRS:
                case RtfControlWord.Ctrl_BRDRSH:
                case RtfControlWord.Ctrl_BRDRT:
                case RtfControlWord.Ctrl_BRDRTH:
                case RtfControlWord.Ctrl_BRDRTHTNLG:
                case RtfControlWord.Ctrl_BRDRTHTNMG:
                case RtfControlWord.Ctrl_BRDRTHTNSG:
                case RtfControlWord.Ctrl_BRDRTNTHLG:
                case RtfControlWord.Ctrl_BRDRTNTHMG:
                case RtfControlWord.Ctrl_BRDRTNTHSG:
                case RtfControlWord.Ctrl_BRDRTNTHTNLG:
                case RtfControlWord.Ctrl_BRDRTNTHTNMG:
                case RtfControlWord.Ctrl_BRDRTNTHTNSG:
                case RtfControlWord.Ctrl_BRDRTRIPLE:
                case RtfControlWord.Ctrl_BRDRW:
                case RtfControlWord.Ctrl_BRDRWAVY:
                case RtfControlWord.Ctrl_BRDRWAVYDB:
                case RtfControlWord.Ctrl_BRSP:
                case RtfControlWord.Ctrl_BOX:
                case RtfControlWord.Ctrl_RTLROW:
                case RtfControlWord.Ctrl_LTRROW:
                case RtfControlWord.Ctrl_TRSPDB:
                case RtfControlWord.Ctrl_TRSPDFB:
                case RtfControlWord.Ctrl_TRSPDFL:
                case RtfControlWord.Ctrl_TRSPDFR:
                case RtfControlWord.Ctrl_TRSPDFT:
                case RtfControlWord.Ctrl_TRSPDL:
                case RtfControlWord.Ctrl_TRSPDR:
                case RtfControlWord.Ctrl_TRSPDT:
                case RtfControlWord.Ctrl_CLMGF:
                case RtfControlWord.Ctrl_CLMRG:
                case RtfControlWord.Ctrl_CLVMGF:
                case RtfControlWord.Ctrl_CLVMRG:
                    HandleTableProperties(token, formatState);
                    break;

                // Symbols
                case RtfControlWord.Ctrl_TAB:
                    ProcessText("\t");
                    break;
                case RtfControlWord.Ctrl_EMDASH:
                    ProcessText("\x2014");
                    break;
                case RtfControlWord.Ctrl_ENDASH:
                    ProcessText("\x2013");
                    break;
                case RtfControlWord.Ctrl_EMSPACE:
                    ProcessText("\x2003");
                    break;
                case RtfControlWord.Ctrl_ENSPACE:
                    ProcessText("\x2002");
                    break;
                case RtfControlWord.Ctrl_QMSPACE:
                    ProcessText("\x2005");
                    break;
                case RtfControlWord.Ctrl_BULLET:
                    ProcessText("\x2022");  // Unicode bullet
                    break;
                case RtfControlWord.Ctrl_LQUOTE:
                    ProcessText("\x2018");
                    break;
                case RtfControlWord.Ctrl_RQUOTE:
                    ProcessText("\x2019");
                    break;
                case RtfControlWord.Ctrl_LDBLQUOTE:
                    ProcessText("\x201c");
                    break;
                case RtfControlWord.Ctrl_RDBLQUOTE:
                    ProcessText("\x201d");
                    break;
                case RtfControlWord.Ctrl_ZWJ:  // zero-width-joiner
                    ProcessText("\x200d");
                    break;
                case RtfControlWord.Ctrl_ZWNJ: // zero-width-non-joiner
                    ProcessText("\x200c");
                    break;

                case RtfControlWord.Ctrl_ANSICPG:
                    // This is just a hint for RTF output roundtripping - ignore.
                    break;

                // CodePage Tokens
                case RtfControlWord.Ctrl_ANSI:
                case RtfControlWord.Ctrl_MAC:
                case RtfControlWord.Ctrl_PC:
                case RtfControlWord.Ctrl_PCA:
                case RtfControlWord.Ctrl_UPR:
                case RtfControlWord.Ctrl_UD:
                case RtfControlWord.Ctrl_UC:
                    HandleCodePageTokens(token, formatState);
                    break;
                case RtfControlWord.Ctrl_U:
                    HandleCodePageTokens(token, formatState);
                    _lexer.AdvanceForUnicode(formatState.UnicodeSkip);
                    break;

                // Field (hyperlink) commands
                case RtfControlWord.Ctrl_FIELD:
                case RtfControlWord.Ctrl_FLDRSLT:
                case RtfControlWord.Ctrl_FLDINST:
                case RtfControlWord.Ctrl_FLDPRIV:
                    HandleFieldTokens(token, formatState);
                    break;

                // Structure commands
                case RtfControlWord.Ctrl_ILVL:
                    formatState.ILVL = token.Parameter;
                    break;
                case RtfControlWord.Ctrl_INTBL:
                    formatState.IsInTable = token.FlagValue;
                    break;

                case RtfControlWord.Ctrl_LS:
                    if (formatState.RtfDestination == RtfDestination.DestListOverride)
                    {
                        HandleListTokens(token, formatState);
                    }
                    else
                    {
                        formatState.ILS = token.Parameter;
                    }
                    break;

                case RtfControlWord.Ctrl_ITAP:
                    formatState.ITAP = token.Parameter;
                    break;

                // Other special parsing commands
                case RtfControlWord.Ctrl_BIN:
                    HandleBinControl(token, formatState);
                    break;

                // List Table commands
                case RtfControlWord.Ctrl_LIST:
                case RtfControlWord.Ctrl_LISTTEMPLATEID:
                case RtfControlWord.Ctrl_LISTHYBRID:
                case RtfControlWord.Ctrl_LISTSIMPLE:
                case RtfControlWord.Ctrl_LISTLEVEL:
                case RtfControlWord.Ctrl_LISTTEXT:
                case RtfControlWord.Ctrl_LEVELNFC:
                case RtfControlWord.Ctrl_LEVELNFCN:
                case RtfControlWord.Ctrl_LEVELJC:
                case RtfControlWord.Ctrl_LEVELJCN:
                case RtfControlWord.Ctrl_LEVELFOLLOW:
                case RtfControlWord.Ctrl_LEVELSTARTAT:
                case RtfControlWord.Ctrl_LEVELSPACE:
                case RtfControlWord.Ctrl_LEVELINDENT:
                case RtfControlWord.Ctrl_LEVELTEXT:
                case RtfControlWord.Ctrl_LEVELTEMPLATEID:
                case RtfControlWord.Ctrl_LISTID:
                case RtfControlWord.Ctrl_LEVELNUMBERS:
                case RtfControlWord.Ctrl_LISTOVERRIDE:
                    HandleListTokens(token, formatState);
                    break;

                case RtfControlWord.Ctrl_LISTPICTURE:
                    formatState.RtfDestination = RtfDestination.DestListPicture;
                    break;

                // Old-style list info
                case RtfControlWord.Ctrl_PNLVL:
                case RtfControlWord.Ctrl_PNLVLBLT:
                case RtfControlWord.Ctrl_PNLVLBODY:
                case RtfControlWord.Ctrl_PNLVLCONT:
                case RtfControlWord.Ctrl_PNCARD:
                case RtfControlWord.Ctrl_PNDEC:
                case RtfControlWord.Ctrl_PNUCLTR:
                case RtfControlWord.Ctrl_PNUCRM:
                case RtfControlWord.Ctrl_PNLCLTR:
                case RtfControlWord.Ctrl_PNLCRM:
                case RtfControlWord.Ctrl_PNORD:
                case RtfControlWord.Ctrl_PNORDT:
                case RtfControlWord.Ctrl_PNBIDIA:
                case RtfControlWord.Ctrl_PNBIDIB:
                case RtfControlWord.Ctrl_PN:
                case RtfControlWord.Ctrl_PNTXTA:
                case RtfControlWord.Ctrl_PNTXTB:
                case RtfControlWord.Ctrl_PNTEXT:
                case RtfControlWord.Ctrl_PNSTART:
                    HandleOldListTokens(token, formatState);
                    break;

                // Shapes (we only read down-level info)
                case RtfControlWord.Ctrl_DO:
                case RtfControlWord.Ctrl_SHPRSLT:
                case RtfControlWord.Ctrl_DPTXBXTEXT:
                case RtfControlWord.Ctrl_SHPPICT:
                case RtfControlWord.Ctrl_NONSHPPICT:
                    HandleShapeTokens(token, formatState);
                    break;

                // Document tables
                case RtfControlWord.Ctrl_FONTTBL:
                    formatState.RtfDestination = RtfDestination.DestFontTable;
                    break;

                case RtfControlWord.Ctrl_COLORTBL:
                    formatState.RtfDestination = RtfDestination.DestColorTable;
                    break;

                case RtfControlWord.Ctrl_LISTTABLE:
                    formatState.RtfDestination = RtfDestination.DestListTable;
                    break;

                case RtfControlWord.Ctrl_LISTOVERRIDETABLE:
                    formatState.RtfDestination = RtfDestination.DestListOverrideTable;
                    break;

                case RtfControlWord.Ctrl_RED:
                    if (formatState.RtfDestination == RtfDestination.DestColorTable)
                    {
                        _converterState.ColorTable.NewRed = (byte)token.Parameter;
                    }
                    break;
                case RtfControlWord.Ctrl_GREEN:
                    if (formatState.RtfDestination == RtfDestination.DestColorTable)
                        _converterState.ColorTable.NewGreen = (byte)token.Parameter;
                    break;
                case RtfControlWord.Ctrl_BLUE:
                    if (formatState.RtfDestination == RtfDestination.DestColorTable)
                    {
                        _converterState.ColorTable.NewBlue = (byte)token.Parameter;
                    }
                    break;
                case RtfControlWord.Ctrl_SHPINST:
                    formatState.RtfDestination = RtfDestination.DestShapeInstruction;
                    break;
                case RtfControlWord.Ctrl_PICT:
                    {
                        FormatState previousFormatState = _converterState.PreviousTopFormatState(1);

                        // Filter the redundant picture or list picture
                        if ((previousFormatState.RtfDestination == RtfDestination.DestShapePicture ||
                             previousFormatState.RtfDestination == RtfDestination.DestShapeInstruction) ||
                            (previousFormatState.RtfDestination != RtfDestination.DestNoneShapePicture &&
                             previousFormatState.RtfDestination != RtfDestination.DestShape &&
                             previousFormatState.RtfDestination != RtfDestination.DestListPicture))
                        {
                            formatState.RtfDestination = RtfDestination.DestPicture;
                        }
                    }
                    break;
                case RtfControlWord.Ctrl_PNGBLIP:
                    if (formatState.RtfDestination == RtfDestination.DestPicture)
                    {
                        formatState.ImageFormat = RtfImageFormat.Png;
                    }
                    break;
                case RtfControlWord.Ctrl_JPEGBLIP:
                    if (formatState.RtfDestination == RtfDestination.DestPicture)
                    {
                        formatState.ImageFormat = RtfImageFormat.Jpeg;
                    }
                    break;
                case RtfControlWord.Ctrl_WMETAFILE:
                    if (formatState.RtfDestination == RtfDestination.DestPicture)
                    {
                        formatState.ImageFormat = RtfImageFormat.Wmf;
                    }
                    break;
                case RtfControlWord.Ctrl_PICHGOAL:
                    if (formatState.RtfDestination == RtfDestination.DestPicture)
                    {
                        formatState.ImageHeight = Converters.TwipToPositivePx(token.Parameter);
                    }
                    break;
                case RtfControlWord.Ctrl_PICWGOAL:
                    if (formatState.RtfDestination == RtfDestination.DestPicture)
                    {
                        formatState.ImageWidth = Converters.TwipToPositivePx(token.Parameter);
                    }
                    break;
                case RtfControlWord.Ctrl_PICSCALEX:
                    if (formatState.RtfDestination == RtfDestination.DestPicture)
                    {
                        formatState.ImageScaleWidth = token.Parameter;
                    }
                    break;
                case RtfControlWord.Ctrl_PICSCALEY:
                    if (formatState.RtfDestination == RtfDestination.DestPicture)
                    {
                        formatState.ImageScaleHeight = token.Parameter;
                    }
                    break;
            }
        }
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        private void SetTokenTextWithControlCharacter(RtfToken token)
        {
            switch (token.Text[0])
            {
                case '~':
                    // NBSP
                    token.Text = new string('\xA0', 1);    // Unicode NBSP
                    break;
                case '-':
                    // Optional hypen (not really in input)
                    token.Text = string.Empty;
                    break;
                case ':':
                    // Sub-entry in index - leave as literal
                    break;
                case '_':
                    // Non-breaking hypen - convert to real hypen
                    token.Text = new string('\x2011', 1);
                    break;
                case '|':
                    // Formula character - leave as literal (or toss?)
                    break;

                // Escaped lexically special RTF characters - leave as literal text
                case '\\':
                case '{':
                case '}':
                    break;
            }
        }
 internal void ProcessColorTableText(RtfToken token)
 {
     // This is just a separator for color table entries
     _converterState.ColorTable.FinishColor();
 }
예제 #10
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;
        }
예제 #11
0
        private void SetRtfIndex(RtfToken token, int controlStartIndex)
        {
            while (_rtfIndex < _rtfBytes.Length && IsControlCharValid(CurByte))
            {
                _rtfIndex++;
            }

            int controlLength = _rtfIndex - controlStartIndex;
            string controlName = CurrentEncoding.GetString(_rtfBytes, controlStartIndex, controlLength);

            // If control sequence > MAX_CONTROL_LENGTH characters, invalid input.
            if (controlLength > MAX_CONTROL_LENGTH)
            {
                token.Type = RtfTokenType.TokenInvalid;
            }
            else
            {
                token.Type = RtfTokenType.TokenControl;
                token.RtfControlWordInfo = RtfControlWordLookup(controlName);

                if (_rtfIndex < _rtfBytes.Length)
                {
                    if (CurByte == ' ')
                    {
                        _rtfIndex++;
                    }
                    else if (IsParameterStart(CurByte))
                    {
                        bool isNegative = false;

                        if (CurByte == '-')
                        {
                            isNegative = true;
                            _rtfIndex++;
                        }

                        long parameter = 0;

                        int paramStartIndex = _rtfIndex;

                        while (_rtfIndex < _rtfBytes.Length && IsParameterFollow(CurByte))
                        {
                            parameter = (parameter * 10) + (CurByte - '0');
                            _rtfIndex++;
                        }

                        int paramLength = _rtfIndex - paramStartIndex;

                        // Following space is not part of text input
                        if (_rtfIndex < _rtfBytes.Length && CurByte == ' ')
                        {
                            _rtfIndex++;
                        }

                        if (isNegative)
                        {
                            parameter = -parameter;
                        }

                        // If parameter is too long, invalid input.
                        if (paramLength > MAX_PARAM_LENGTH)
                        {
                            token.Type = RtfTokenType.TokenInvalid;
                        }
                        else
                        {
                            token.Parameter = parameter;
                        }
                    }
                }
            }
        }
예제 #12
0
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        /// <summary>
        /// Called to process sequence of text and \'hh encoded bytes.
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private RtfToXamlError NextText(RtfToken token)
        {
            RtfToXamlError rtfToXamlError = RtfToXamlError.None;

            _rtfLastIndex = _rtfIndex;

            token.Empty();
            token.Type = RtfTokenType.TokenText;

            int s = _rtfIndex;
            int e = s;
            bool bSawHex = false;

            while (e < _rtfBytes.Length)
            {
                if (IsControl(_rtfBytes[e]))
                {
                    if (_rtfBytes[e] == (byte)'\\'
                        && e + 3 < _rtfBytes.Length
                        && _rtfBytes[e + 1] == '\''
                        && IsHex(_rtfBytes[e + 2])
                        && IsHex(_rtfBytes[e + 3]))
                    {
                        e += 4;
                        bSawHex = true;
                    }
                    else
                    {
                        break;
                    }
                }
                else if (_rtfBytes[e] == '\r' || _rtfBytes[e] == '\n' || _rtfBytes[e] == 0)
                {
                    break;
                }
                else
                {
                    e++;
                }
            }

            if (s == e)
            {
                token.Type = RtfTokenType.TokenInvalid;
            }
            else
            {
                _rtfIndex = e;

                if (bSawHex)
                {
                    int i = 0;
                    int n = e - s;
                    byte[] bytes = new byte[n];
                    while (s < e)
                    {
                        if (_rtfBytes[s] == '\\')
                        {
                            bytes[i++] = (byte)((byte)(HexToByte(_rtfBytes[s + 2]) << 4) + HexToByte(_rtfBytes[s + 3]));
                            s += 4;
                        }
                        else
                        {
                            bytes[i++] = _rtfBytes[s++];
                        }
                    }

                    token.Text = CurrentEncoding.GetString(bytes, 0, i);
                }
                else
                {
                    token.Text = CurrentEncoding.GetString(_rtfBytes, s, e - s);
                }
            }

            return rtfToXamlError;
        }
예제 #13
0
        internal RtfToXamlError AdvanceForUnicode(long nSkip)
        {
            RtfToXamlError rtfToXamlError = RtfToXamlError.None;

            // Advancing for text is a little tricky
            RtfToken token = new RtfToken();
            while (nSkip > 0 && rtfToXamlError == RtfToXamlError.None)
            {
                rtfToXamlError = Next(token, /*formatState:*/null);

                if (rtfToXamlError != RtfToXamlError.None)
                    break;

                switch (token.Type)
                {
                    default:
                    case RtfTokenType.TokenGroupStart:
                    case RtfTokenType.TokenGroupEnd:
                    case RtfTokenType.TokenInvalid:
                    case RtfTokenType.TokenEOF:
                    case RtfTokenType.TokenDestination:
                        Backup();
                        nSkip = 0;
                        break;

                    case RtfTokenType.TokenControl:
                        if (token.RtfControlWordInfo != null && token.RtfControlWordInfo.Control == RtfControlWord.Ctrl_BIN)
                        {
                            AdvanceForBinary((int)token.Parameter);
                        }
                        nSkip--;
                        break;

                    case RtfTokenType.TokenNewline:
                        // Newlines don't count for skipping purposes
                        break;

                    case RtfTokenType.TokenNullChar:
                        // Null chars don't count for skipping purposes
                        break;

                    case RtfTokenType.TokenText:
                        // We need to skip *bytes*, considering hex-encoded control words as a single byte.
                        // Since Next() returned TokenText, we know that we can safely assume that the next
                        // sequence of bytes is either simple text or hex-encoded bytes.
                        int nEndTextIndex = _rtfIndex;
                        Backup();
                        while (nSkip > 0 && _rtfIndex < nEndTextIndex)
                        {
                            if (CurByte == '\\')
                            {
                                _rtfIndex += 4;
                            }
                            else
                            {
                                _rtfIndex++;
                            }
                            nSkip--;
                        }
                        break;
                }
            }

            return rtfToXamlError;
        }
        // Token: 0x060032B5 RID: 12981 RVA: 0x000E40E0 File Offset: 0x000E22E0
        private RtfToXamlError NextText(RtfToken token)
        {
            RtfToXamlError result = RtfToXamlError.None;

            this._rtfLastIndex = this._rtfIndex;
            token.Empty();
            token.Type = RtfTokenType.TokenText;
            int  i    = this._rtfIndex;
            int  j    = i;
            bool flag = false;

            while (j < this._rtfBytes.Length)
            {
                if (this.IsControl(this._rtfBytes[j]))
                {
                    if (this._rtfBytes[j] != 92 || j + 3 >= this._rtfBytes.Length || this._rtfBytes[j + 1] != 39 || !this.IsHex(this._rtfBytes[j + 2]) || !this.IsHex(this._rtfBytes[j + 3]))
                    {
                        break;
                    }
                    j   += 4;
                    flag = true;
                }
                else
                {
                    if (this._rtfBytes[j] == 13 || this._rtfBytes[j] == 10 || this._rtfBytes[j] == 0)
                    {
                        break;
                    }
                    j++;
                }
            }
            if (i == j)
            {
                token.Type = RtfTokenType.TokenInvalid;
            }
            else
            {
                this._rtfIndex = j;
                if (flag)
                {
                    int    count = 0;
                    int    num   = j - i;
                    byte[] array = new byte[num];
                    while (i < j)
                    {
                        if (this._rtfBytes[i] == 92)
                        {
                            array[count++] = (byte)(this.HexToByte(this._rtfBytes[i + 2]) << 4) + this.HexToByte(this._rtfBytes[i + 3]);
                            i += 4;
                        }
                        else
                        {
                            array[count++] = this._rtfBytes[i++];
                        }
                    }
                    token.Text = this.CurrentEncoding.GetString(array, 0, count);
                }
                else
                {
                    token.Text = this.CurrentEncoding.GetString(this._rtfBytes, i, j - i);
                }
            }
            return(result);
        }
예제 #15
0
        private void SetRtfIndex(RtfToken token, int controlStartIndex)
        {
            while (_rtfIndex < _rtfBytes.Length && IsControlCharValid(CurByte))
            {
                _rtfIndex++;
            }

            int    controlLength = _rtfIndex - controlStartIndex;
            string controlName   = CurrentEncoding.GetString(_rtfBytes, controlStartIndex, controlLength);

            // If control sequence > MAX_CONTROL_LENGTH characters, invalid input.
            if (controlLength > MAX_CONTROL_LENGTH)
            {
                token.Type = RtfTokenType.TokenInvalid;
            }
            else
            {
                token.Type = RtfTokenType.TokenControl;
                token.RtfControlWordInfo = RtfControlWordLookup(controlName);

                if (_rtfIndex < _rtfBytes.Length)
                {
                    if (CurByte == ' ')
                    {
                        _rtfIndex++;
                    }
                    else if (IsParameterStart(CurByte))
                    {
                        bool isNegative = false;

                        if (CurByte == '-')
                        {
                            isNegative = true;
                            _rtfIndex++;
                        }

                        long parameter = 0;

                        int paramStartIndex = _rtfIndex;

                        while (_rtfIndex < _rtfBytes.Length && IsParameterFollow(CurByte))
                        {
                            parameter = (parameter * 10) + (CurByte - '0');
                            _rtfIndex++;
                        }

                        int paramLength = _rtfIndex - paramStartIndex;

                        // Following space is not part of text input
                        if (_rtfIndex < _rtfBytes.Length && CurByte == ' ')
                        {
                            _rtfIndex++;
                        }

                        if (isNegative)
                        {
                            parameter = -parameter;
                        }

                        // If parameter is too long, invalid input.
                        if (paramLength > MAX_PARAM_LENGTH)
                        {
                            token.Type = RtfTokenType.TokenInvalid;
                        }
                        else
                        {
                            token.Parameter = parameter;
                        }
                    }
                }
            }
        }
        // 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 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;
            }
        }
        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 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 Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        /// <summary>
        /// RtfToXamlError process
        /// </summary>
        internal RtfToXamlError Process()
        {
            RtfToXamlError rtfToXamlError = RtfToXamlError.None;

            RtfToken token = new RtfToken();
            bool findUnknownDestinationToken = false;

            int nStartCount = _converterState.RtfFormatStack.Count;

            while (rtfToXamlError == RtfToXamlError.None)
            {
                rtfToXamlError = _lexer.Next(token, _converterState.TopFormatState);

                if (rtfToXamlError != RtfToXamlError.None)
                {
                    break;
                }

                switch (token.Type)
                {
                    case RtfTokenType.TokenGroupStart:
                        _converterState.RtfFormatStack.Push();
                        findUnknownDestinationToken = false;
                        break;

                    case RtfTokenType.TokenGroupEnd:
                        ProcessGroupEnd();
                        findUnknownDestinationToken = false;
                        break;

                    case RtfTokenType.TokenInvalid:
                        rtfToXamlError = RtfToXamlError.InvalidFormat;
                        break;

                    case RtfTokenType.TokenEOF:
                        // Handle any anomalous missing group ends.
                        while (_converterState.RtfFormatStack.Count > 2 && _converterState.RtfFormatStack.Count > nStartCount)
                            ProcessGroupEnd();

                        AppendDocument();

                        return RtfToXamlError.None;

                    case RtfTokenType.TokenDestination:
                        findUnknownDestinationToken = true;
                        break;

                    case RtfTokenType.TokenControl:
                        {
                            RtfControlWordInfo controlWordInfo = token.RtfControlWordInfo;

                            if (controlWordInfo != null && !findUnknownDestinationToken)
                            {
                                if ((controlWordInfo.Flags & RtfControls.RTK_DESTINATION) != 0)
                                {
                                    findUnknownDestinationToken = true;
                                }
                            }

                            if (findUnknownDestinationToken)
                            {
                                // Ignore unknown control on the current field result destination.
                                // Otherwise, the field result content will be ignoreed by the unknown rtf destination.
                                if (controlWordInfo != null &&
                                    controlWordInfo.Control == RtfControlWord.Ctrl_Unknown &&
                                    _converterState.TopFormatState.RtfDestination == RtfDestination.DestFieldResult)
                                {
                                    controlWordInfo = null;
                                }
                                else
                                {
                                    _converterState.TopFormatState.RtfDestination = RtfDestination.DestUnknown;
                                }
                                findUnknownDestinationToken = false;
                            }

                            if (controlWordInfo != null)
                            {
                                HandleControl(token, controlWordInfo);
                            }

                            break;
                        }

                    case RtfTokenType.TokenText:
                        ProcessText(token);
                        break;

                    case RtfTokenType.TokenTextSymbol:
                        ProcessTextSymbol(token);
                        break;

                    case RtfTokenType.TokenNewline:
                    case RtfTokenType.TokenNullChar:
                        // Eaten
                        break;

                    case RtfTokenType.TokenPictureData:
                        ProcessImage(_converterState.TopFormatState);
                        break;
                }
            }

            return rtfToXamlError;
        }
        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 ProcessText(RtfToken token)
        {
            FormatState fs = _converterState.TopFormatState;
            if (fs.IsHidden)
            {
                return;
            }

            switch (fs.RtfDestination)
            {
                case RtfDestination.DestFieldResult:
                case RtfDestination.DestShapeResult:
                case RtfDestination.DestNormal:
                case RtfDestination.DestListText:
                    HandleNormalText(token.Text, fs);
                    break;
                case RtfDestination.DestFontTable:
                case RtfDestination.DestFontName:
                    ProcessFontTableText(token);
                    break;
                case RtfDestination.DestColorTable:
                    ProcessColorTableText(token);
                    break;
                case RtfDestination.DestField:
                case RtfDestination.DestFieldInstruction:
                case RtfDestination.DestFieldPrivate:
                    ProcessFieldText(token);
                    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 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 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);
        }
        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 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 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 ProcessFieldText(RtfToken token)
 {
     switch (_converterState.TopFormatState.RtfDestination)
     {
         case RtfDestination.DestField:
             break;
         case RtfDestination.DestFieldInstruction:
             // Gather up for later processing
             HandleNormalText(token.Text, _converterState.TopFormatState);
             break;
         case RtfDestination.DestFieldPrivate:
             // Discard
             break;
         case RtfDestination.DestFieldResult:
             HandleNormalText(token.Text, _converterState.TopFormatState);
             break;
     }
 }
예제 #30
0
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        /// <summary>
        /// Called to process sequence of text and \'hh encoded bytes.
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private RtfToXamlError NextText(RtfToken token)
        {
            RtfToXamlError rtfToXamlError = RtfToXamlError.None;

            _rtfLastIndex = _rtfIndex;

            token.Empty();
            token.Type = RtfTokenType.TokenText;

            int  s       = _rtfIndex;
            int  e       = s;
            bool bSawHex = false;

            while (e < _rtfBytes.Length)
            {
                if (IsControl(_rtfBytes[e]))
                {
                    if (_rtfBytes[e] == (byte)'\\' &&
                        e + 3 < _rtfBytes.Length &&
                        _rtfBytes[e + 1] == '\'' &&
                        IsHex(_rtfBytes[e + 2]) &&
                        IsHex(_rtfBytes[e + 3]))
                    {
                        e      += 4;
                        bSawHex = true;
                    }
                    else
                    {
                        break;
                    }
                }
                else if (_rtfBytes[e] == '\r' || _rtfBytes[e] == '\n' || _rtfBytes[e] == 0)
                {
                    break;
                }
                else
                {
                    e++;
                }
            }

            if (s == e)
            {
                token.Type = RtfTokenType.TokenInvalid;
            }
            else
            {
                _rtfIndex = e;

                if (bSawHex)
                {
                    int    i     = 0;
                    int    n     = e - s;
                    byte[] bytes = new byte[n];
                    while (s < e)
                    {
                        if (_rtfBytes[s] == '\\')
                        {
                            bytes[i++] = (byte)((byte)(HexToByte(_rtfBytes[s + 2]) << 4) + HexToByte(_rtfBytes[s + 3]));
                            s         += 4;
                        }
                        else
                        {
                            bytes[i++] = _rtfBytes[s++];
                        }
                    }

                    token.Text = CurrentEncoding.GetString(bytes, 0, i);
                }
                else
                {
                    token.Text = CurrentEncoding.GetString(_rtfBytes, s, e - s);
                }
            }

            return(rtfToXamlError);
        }
        internal void ProcessFontTableText(RtfToken token)
        {
            string tokenName = token.Text;

            // Strip line endings
            tokenName = tokenName.Replace("\r\n", "");
            // Strip trailing semi-colon
            tokenName = tokenName.Replace(";", "");

            FontTableEntry entry = _converterState.FontTable.CurrentEntry;

            if (entry != null && tokenName.Length > 0 && !entry.IsNameSealed)
            {
                // If name not yet specified, just set it
                if (entry.Name == null)
                {
                    entry.Name = tokenName;
                }
                else // Otherwise, append it
                {
                    entry.Name += tokenName;
                }
            }
        }
예제 #32
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);
        }
        internal void HandleFontTableTokens(RtfToken token)
        {
            FontTableEntry entry = _converterState.FontTable.CurrentEntry;
            FormatState formatState = _converterState.TopFormatState;

            if (entry != null)
            {
                switch (token.RtfControlWordInfo.Control)
                {
                    case RtfControlWord.Ctrl_FCHARSET:
                        // Set the codepage to the font table entry
                        entry.CodePageFromCharSet = (int)token.Parameter;

                        // Also set lexer code page
                        if (entry.CodePage == -1)
                        {
                            formatState.CodePage = _converterState.CodePage;
                        }
                        else
                        {
                            formatState.CodePage = entry.CodePage;
                        }
                        _lexer.CodePage = formatState.CodePage;
                        break;
                }
            }
        }