// 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); }
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(); }
//------------------------------------------------------ // // 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; }
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; } } } } }
//------------------------------------------------------ // // 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 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); }
// 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; } }
//------------------------------------------------------ // // 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; } } }
//------------------------------------------------------ // // 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; } } }