// Token: 0x0600329A RID: 12954 RVA: 0x000E3B2C File Offset: 0x000E1D2C internal void Push() { FormatState formatState = this.Top(); FormatState value = (formatState != null) ? new FormatState(formatState) : new FormatState(); this.Add(value); }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods internal void Push() { FormatState previousFormatState = Top(); FormatState formatState; formatState = previousFormatState != null ? new FormatState(previousFormatState) : new FormatState(); Add(formatState); }
// Token: 0x060032DB RID: 13019 RVA: 0x000E5194 File Offset: 0x000E3394 internal FormatState(FormatState formatState) { this.Bold = formatState.Bold; this.Italic = formatState.Italic; this.Engrave = formatState.Engrave; this.Shadow = formatState.Shadow; this.SCaps = formatState.SCaps; this.Outline = formatState.Outline; this.Super = formatState.Super; this.Sub = formatState.Sub; this.SuperOffset = formatState.SuperOffset; this.FontSize = formatState.FontSize; this.Font = formatState.Font; this.CodePage = formatState.CodePage; this.CF = formatState.CF; this.CB = formatState.CB; this.DirChar = formatState.DirChar; this.UL = formatState.UL; this.Strike = formatState.Strike; this.Expand = formatState.Expand; this.Lang = formatState.Lang; this.LangFE = formatState.LangFE; this.LangCur = formatState.LangCur; this.FontSlot = formatState.FontSlot; this.SB = formatState.SB; this.SA = formatState.SA; this.FI = formatState.FI; this.RI = formatState.RI; this.LI = formatState.LI; this.SL = formatState.SL; this.SLMult = formatState.SLMult; this.HAlign = formatState.HAlign; this.ILVL = formatState.ILVL; this.ITAP = formatState.ITAP; this.ILS = formatState.ILS; this.DirPara = formatState.DirPara; this.CFPara = formatState.CFPara; this.CBPara = formatState.CBPara; this.ParaShading = formatState.ParaShading; this.Marker = formatState.Marker; this.IsContinue = formatState.IsContinue; this.StartIndex = formatState.StartIndex; this.StartIndexDefault = formatState.StartIndexDefault; this.IsInTable = formatState.IsInTable; this._pb = (formatState.HasParaBorder ? new ParaBorder(formatState.ParaBorder) : null); this.RowFormat = formatState._rowFormat; this.RtfDestination = formatState.RtfDestination; this.IsHidden = formatState.IsHidden; this._stateSkip = formatState.UnicodeSkip; }
internal void HandlePara(RtfToken token, FormatState formatState) { // Ignore \par in other destinations if (!formatState.IsContentDestination || formatState.IsHidden) { return; } // Arrival of paragraph tag allows us to rationalize structure information. // Various tags have told us things about this paragraph: // \INTBL: Paragraph is inside a table cell. // \ITAP{N}: Nesting level for table. Note that I may not have yet // seen any tags that start the nested table. // \LS{N}: Listtable override index. Any value indicates this paragraph // is in a list. // \ILVL: Nesting level for list. // If we're in a throw-away destination, just return. HandleParagraphFromText(formatState); // Make sure proper number of tables are open to reflect this paragraphs nest level HandleTableNesting(formatState); // Now handle lists, which always behave as if they are inside tables. HandleListNesting(formatState); }
private void ProcessRtfDestination(FormatState fsCur) { DocumentNodeArray dna = _converterState.DocumentNodeArray; int nAt; switch (fsCur.RtfDestination) { case RtfDestination.DestField: nAt = dna.FindUnmatched(DocumentNodeType.dnFieldBegin); if (nAt >= 0) { DocumentNode dnEnd = new DocumentNode(DocumentNodeType.dnFieldEnd); dnEnd.FormatState = new FormatState(fsCur); dnEnd.IsPending = false; dna.Push(dnEnd); dna.EntryAt(nAt).IsMatched = true; ProcessField(); } break; case RtfDestination.DestFieldInstruction: case RtfDestination.DestFieldPrivate: case RtfDestination.DestFieldResult: nAt = dna.FindUnmatched(DocumentNodeType.dnFieldBegin); if (nAt >= 0) { DocumentNode dnEnd = new DocumentNode(DocumentNodeType.dnFieldEnd); dnEnd.FormatState = new FormatState(fsCur); dnEnd.IsPending = false; dna.Push(dnEnd); dna.EntryAt(nAt).IsMatched = true; } break; // The DestShape destination is only to distinguish the case of leaving a shaperesult destination // when shapes were nested. No processing is actually necessary here. case RtfDestination.DestShape: break; case RtfDestination.DestShapeResult: ProcessShapeResult(); break; case RtfDestination.DestListText: ProcessListText(); break; case RtfDestination.DestListLevel: { ListTableEntry listTableEntry = _converterState.ListTable.CurrentEntry; if (listTableEntry != null) { ListLevel listLevel = listTableEntry.Levels.CurrentEntry; listLevel.FormatState = new FormatState(fsCur); } } break; case RtfDestination.DestListOverride: break; case RtfDestination.DestList: break; case RtfDestination.DestFontName: FontTableEntry entry = _converterState.FontTable.CurrentEntry; if (entry != null) { entry.IsNameSealed = true; entry.IsPending = false; } break; case RtfDestination.DestFontTable: _converterState.FontTable.MapFonts(); break; } }
internal void ProcessImage(FormatState formatState) { string contentType; string imagePartUriString; switch (formatState.ImageFormat) { case RtfImageFormat.Wmf: case RtfImageFormat.Png: contentType = "image/png"; break; case RtfImageFormat.Jpeg: contentType = "image/jpeg"; break; default: contentType = string.Empty; break; } bool skipImage = (formatState.ImageScaleWidth < 0) || (formatState.ImageScaleHeight < 0); if (_wpfPayload != null && contentType != string.Empty && !skipImage) { // Get image part URI string and image binary steam to write Rtf image data // into the container of WpfPayload Stream imageStream = _wpfPayload.CreateImageStream(_imageCount, contentType, out imagePartUriString); using (imageStream) { if (formatState.ImageFormat != RtfImageFormat.Wmf) { // Write the image binary data on the container from Rtf image data _lexer.WriteImageData(imageStream, formatState.IsImageDataBinary); } else { // Read the windows metafile from the rtf content and then convert it // to bitmap data then save it as PNG on the container image part MemoryStream metafileStream = new MemoryStream(); ; using (metafileStream) { // Get Windows Metafile from rtf content _lexer.WriteImageData(metafileStream, formatState.IsImageDataBinary); metafileStream.Position = 0; SystemDrawingHelper.SaveMetafileToImageStream(metafileStream, imageStream); } } } // Increase the image count to generate the image source name _imageCount++; formatState.ImageSource = imagePartUriString; // Create the image document node DocumentNode dnImage = new DocumentNode(DocumentNodeType.dnImage); dnImage.FormatState = formatState; StringBuilder imageStringBuilder = new StringBuilder(); // Add the xaml image element imageStringBuilder.Append("<Image "); // Add the xaml image width property imageStringBuilder.Append(" Width=\""); double width; if (formatState.ImageScaleWidth != 0) { width = formatState.ImageWidth * (formatState.ImageScaleWidth / 100); } else { width = formatState.ImageWidth; } imageStringBuilder.Append(width.ToString(CultureInfo.InvariantCulture)); imageStringBuilder.Append("\""); // Add the xaml image height property imageStringBuilder.Append(" Height=\""); double height = formatState.ImageHeight * (formatState.ImageScaleHeight / 100); if (formatState.ImageScaleHeight != 0) { height = formatState.ImageHeight * (formatState.ImageScaleHeight / 100); } else { height = formatState.ImageHeight; } imageStringBuilder.Append(height.ToString(CultureInfo.InvariantCulture)); imageStringBuilder.Append("\""); // Add the xaml image stretch property imageStringBuilder.Append(" Stretch=\"Fill"); imageStringBuilder.Append("\""); // Add the xaml image close tag imageStringBuilder.Append(">"); // Add the image source property as the complex property // This is for specifying BitmapImage.CacheOption as OnLoad instead of // the default OnDemand option. imageStringBuilder.Append("<Image.Source>"); imageStringBuilder.Append("<BitmapImage "); imageStringBuilder.Append("UriSource=\""); imageStringBuilder.Append(imagePartUriString); imageStringBuilder.Append("\" "); imageStringBuilder.Append("CacheOption=\"OnLoad\" "); imageStringBuilder.Append("/>"); imageStringBuilder.Append("</Image.Source>"); imageStringBuilder.Append("</Image>"); // Set Xaml for image element dnImage.Xaml = imageStringBuilder.ToString(); // Insert the image document node to the document node array DocumentNodeArray dna = _converterState.DocumentNodeArray; dna.Push(dnImage); dna.CloseAt(dna.Count - 1); } else { // Skip the image data if the image type is unknown or WpfPayload is null _lexer.AdvanceForImageData(); } }
internal void ConstrainFontPropagation(FormatState fsOrig) { // We only output certain font properties at the paragraph level. Ensure the paragraph's formatstate // only records those properties that are actually written there, so that inline nodes properly // generate the result. FormatState.SetCharDefaults(); FormatState.Font = fsOrig.Font; FormatState.FontSize = fsOrig.FontSize; FormatState.Bold = fsOrig.Bold; FormatState.Italic = fsOrig.Italic; // No, lang can't be written at paragraph level since I have no way of turning it "off", e.g. if // \lang specified for \par but not for inline text. // FormatState.LangCur = fsOrig.LangCur; // No, font color can't be written at paragraph level since I have no way of turning it "off" once // I've turned it on, so "automatic" color values can't be encoded. I'll just have to skip it here. // FormatState.CF = fsOrig.CF; // No, text decorations can't be written at paragraph level since they don't propagate. // FormatState.UL = fsOrig.UL; // FormatState.Strike = fsOrig.Strike; }
//------------------------------------------------------ // // Constructors // //------------------------------------------------------ #region Constructors internal DocumentNode(DocumentNodeType documentNodeType) { _type = documentNodeType; _bPending = true; _childCount = 0; _index = -1; _dna = null; _parent = null; _bTerminated = false; _bMatched = false; _bHasMarkerContent = false; _sCustom = null; _nRowSpan = 1; _nColSpan = 1; _nVirtualListLevel = -1; _csa = null; _formatState = new FormatState(); _contentBuilder = new StringBuilder(); }
private int GetMatchedMarkList(FormatState formatState, MarkerList mlHave, MarkerList mlWant) { // The ones we have are only "good" if the styles match what we want. int nMatch = 0; for (; nMatch < mlHave.Count && nMatch < mlWant.Count; nMatch++) { if (!formatState.IsContinue) { MarkerListEntry eHave = mlHave.EntryAt(nMatch); MarkerListEntry eWant = mlWant.EntryAt(nMatch); if (eHave.Marker != eWant.Marker || eHave.ILS != eWant.ILS || eHave.StartIndexDefault != eWant.StartIndexDefault || eWant.StartIndexOverride >= 0) { break; } } } return nMatch; }
internal void HandleShapeTokens(RtfToken token, FormatState formatState) { DocumentNodeArray dna = _converterState.DocumentNodeArray; FormatState fsCur = _converterState.PreviousTopFormatState(0); FormatState fsOld = _converterState.PreviousTopFormatState(1); if (fsCur == null || fsOld == null) { return; } switch (token.RtfControlWordInfo.Control) { case RtfControlWord.Ctrl_DO: // Just propagate destination through this keyword. fsCur.RtfDestination = fsOld.RtfDestination; break; case RtfControlWord.Ctrl_SHPRSLT: if (fsOld.IsContentDestination) { fsCur.RtfDestination = RtfDestination.DestShape; } break; case RtfControlWord.Ctrl_DPTXBXTEXT: if (fsOld.IsContentDestination) { // Track the destination so I can recognize when we leave this scope. fsCur.RtfDestination = RtfDestination.DestShapeResult; // Wrap any inline content that occurs before this shape anchor in a paragraph, // since the shape content itself will be block level. WrapPendingInlineInParagraph(token, formatState); DocumentNodeType t = dna.GetTableScope(); if (t != DocumentNodeType.dnParagraph) { if (t == DocumentNodeType.dnTableBody) { // If row has been closed, close overall table as well. int nAt = dna.FindPending(DocumentNodeType.dnTable); if (nAt >= 0) { dna.CloseAt(nAt); dna.CoalesceChildren(_converterState, nAt); } } else { // If I'm inside a table, reopen last cell to insert shape contents. Otherwise // table gets torqued. dna.OpenLastCell(); } } // The shape node generates no output but plays a large role in changing the // behavior of the "FindPending" routines to keep from looking outside this scope. DocumentNode dn = new DocumentNode(DocumentNodeType.dnShape); formatState.SetParaDefaults(); formatState.SetCharDefaults(); dn.FormatState = new FormatState(formatState); dna.Push(dn); } break; case RtfControlWord.Ctrl_SHPPICT: // If this occurs in listtext context, mark listtext as non-empty. int ndnListText = dna.FindPending(DocumentNodeType.dnListText); if (ndnListText >= 0) { DocumentNode dnListText = dna.EntryAt(ndnListText); dnListText.HasMarkerContent = true; } // Keep the rtf destination as the list picture to skip the list picture if (fsOld.RtfDestination == RtfDestination.DestListPicture) { formatState.RtfDestination = RtfDestination.DestListPicture; } else { formatState.RtfDestination = RtfDestination.DestShapePicture; } break; case RtfControlWord.Ctrl_NONSHPPICT: formatState.RtfDestination = RtfDestination.DestNoneShapePicture; break; } }
internal void HandleListTokens(RtfToken token, FormatState formatState) { ListTable listTable = _converterState.ListTable; ListOverrideTable listOverrideTable = _converterState.ListOverrideTable; FormatState fsCur = _converterState.PreviousTopFormatState(0); FormatState fsOld = _converterState.PreviousTopFormatState(1); if (fsCur == null || fsOld == null) { return; } switch (token.RtfControlWordInfo.Control) { case RtfControlWord.Ctrl_LIST: if (formatState.RtfDestination == RtfDestination.DestListTable) { ListTableEntry listTableEntry = listTable.AddEntry(); } break; case RtfControlWord.Ctrl_LISTTEMPLATEID: { ListTableEntry listTableEntry = listTable.CurrentEntry; if (listTableEntry != null) { listTableEntry.TemplateID = token.Parameter; } } break; case RtfControlWord.Ctrl_LISTHYBRID: case RtfControlWord.Ctrl_LISTSIMPLE: { ListTableEntry listTableEntry = listTable.CurrentEntry; if (listTableEntry != null) { listTableEntry.Simple = token.RtfControlWordInfo.Control == RtfControlWord.Ctrl_LISTSIMPLE; } } break; case RtfControlWord.Ctrl_LISTLEVEL: { formatState.RtfDestination = RtfDestination.DestListLevel; ListLevelTable levels = GetControllingLevelTable(); if (levels != null) { ListLevel listLevel = levels.AddEntry(); } } break; case RtfControlWord.Ctrl_LISTTEXT: if (fsOld.IsContentDestination || formatState.IsHidden) { formatState.RtfDestination = RtfDestination.DestListText; DocumentNodeArray dna = _converterState.DocumentNodeArray; DocumentNode dnl = new DocumentNode(DocumentNodeType.dnListText); dnl.FormatState = new FormatState(formatState); dna.Push(dnl); } break; case RtfControlWord.Ctrl_LEVELNFC: case RtfControlWord.Ctrl_LEVELNFCN: { ListLevelTable levels = GetControllingLevelTable(); if (levels != null) { ListLevel listLevel = levels.CurrentEntry; if (listLevel != null) { listLevel.Marker = (MarkerStyle)token.Parameter; } } } break; case RtfControlWord.Ctrl_LEVELJC: case RtfControlWord.Ctrl_LEVELJCN: // NB: Marker alignment not supported in XAML. break; case RtfControlWord.Ctrl_LEVELFOLLOW: break; case RtfControlWord.Ctrl_LEVELSTARTAT: { ListLevelTable levels = GetControllingLevelTable(); if (levels != null) { ListLevel listLevel = levels.CurrentEntry; if (listLevel != null) { listLevel.StartIndex = token.Parameter; } else { // This is the case where the list override *only* specifies startat override. ListOverride lo = GetControllingListOverride(); if (lo != null) { lo.StartIndex = token.Parameter; } } } } break; case RtfControlWord.Ctrl_LEVELSPACE: break; case RtfControlWord.Ctrl_LEVELINDENT: break; case RtfControlWord.Ctrl_LEVELTEXT: break; case RtfControlWord.Ctrl_LEVELTEMPLATEID: break; case RtfControlWord.Ctrl_LISTID: { if (formatState.RtfDestination == RtfDestination.DestListOverride) { ListOverride listOverride = listOverrideTable.CurrentEntry; if (listOverride != null) { listOverride.ID = token.Parameter; } } else { ListTableEntry listTableEntry = listTable.CurrentEntry; if (listTableEntry != null) { listTableEntry.ID = token.Parameter; } } } break; case RtfControlWord.Ctrl_LEVELNUMBERS: break; case RtfControlWord.Ctrl_LISTOVERRIDE: { FormatState previousFormatState = _converterState.PreviousTopFormatState(1); if (previousFormatState.RtfDestination == RtfDestination.DestListOverrideTable) { formatState.RtfDestination = RtfDestination.DestListOverride; ListOverride listOverride = listOverrideTable.AddEntry(); } } break; case RtfControlWord.Ctrl_LS: if (formatState.RtfDestination == RtfDestination.DestListOverride) { ListOverride listOverride = listOverrideTable.CurrentEntry; if (listOverride != null) { listOverride.Index = token.Parameter; } } break; } }
private bool WriteParagraphListInfo(DocumentNode dnThis, FormatState fsThis) { bool bOutControl = false; bool bNewStyle = GenerateListTables; if (dnThis.ListLabel != null) { DocumentNode dnList = dnThis.GetParentOfType(DocumentNodeType.dnList); if (dnList != null) { // Old style list info for RichEdit and other non-Word client compat if I can. // Only do this for simple, non multi-level lists. if (bNewStyle && dnList.FormatState.PNLVL == 1) { bNewStyle = false; } if (bNewStyle) { _rtfBuilder.Append("{\\listtext "); _rtfBuilder.Append(dnThis.ListLabel); if (dnList.FormatState.Marker != MarkerStyle.MarkerBullet && dnList.FormatState.Marker != MarkerStyle.MarkerNone) { _rtfBuilder.Append("."); } _rtfBuilder.Append("\\tab}"); // NB: RichEdit requires \ls keyword to occur immediately after \listtext if (fsThis.ILS > 0) { _rtfBuilder.Append("\\ls"); _rtfBuilder.Append(fsThis.ILS.ToString(CultureInfo.InvariantCulture)); bOutControl = true; } if (fsThis.ILVL > 0) { _rtfBuilder.Append("\\ilvl"); _rtfBuilder.Append(fsThis.ILVL.ToString(CultureInfo.InvariantCulture)); bOutControl = true; } } else { _rtfBuilder.Append("{\\pntext "); _rtfBuilder.Append(dnThis.ListLabel); if (dnList.FormatState.Marker != MarkerStyle.MarkerBullet && dnList.FormatState.Marker != MarkerStyle.MarkerNone) { _rtfBuilder.Append("."); } _rtfBuilder.Append("\\tab}{\\*\\pn"); _rtfBuilder.Append(Converters.MarkerStyleToOldRTFString(dnList.FormatState.Marker)); if (fsThis.ListLevel > 0 && dnList.FormatState.PNLVL > 1) { _rtfBuilder.Append("\\pnlvl"); _rtfBuilder.Append(fsThis.ListLevel.ToString(CultureInfo.InvariantCulture)); } if (fsThis.FI > 0) { _rtfBuilder.Append("\\pnhang"); } if (fsThis.StartIndex >= 0) { _rtfBuilder.Append("\\pnstart"); _rtfBuilder.Append(fsThis.StartIndex.ToString(CultureInfo.InvariantCulture)); } if (dnList.FormatState.Marker == MarkerStyle.MarkerBullet) { _rtfBuilder.Append("{\\pntxtb\\'B7}}"); } else if (dnList.FormatState.Marker == MarkerStyle.MarkerNone) { _rtfBuilder.Append("{\\pntxta }{\\pntxtb }}"); } else { _rtfBuilder.Append("{\\pntxta .}}"); } // Already terminated with curly, no need for extra space. bOutControl = false; } } } return bOutControl; }
private bool WriteParagraphFontInfo(DocumentNode dnThis, FormatState fsThis, FormatState fsParent) { int nStart = dnThis.Index + 1; int nEnd = dnThis.Index + dnThis.ChildCount; int nAt; DocumentNodeArray dna = _converterState.DocumentNodeArray; bool bOutControl = false; // In order to minimize RTF output, pull fontsize and font info into paragraph level if possible long fsAll = -2; long fontAll = -2; for (nAt = nStart; nAt <= nEnd; nAt++) { DocumentNode dnChild = dna.EntryAt(nAt); if (dnChild.Parent == dnThis) { if (fsAll == -2) { fsAll = dnChild.FormatState.FontSize; } else if (fsAll != dnChild.FormatState.FontSize) { fsAll = -3; } if (fontAll == -2) { fontAll = dnChild.FormatState.Font; } else if (fontAll != dnChild.FormatState.Font) { fontAll = -3; } } } if (fsAll >= 0) { fsThis.FontSize = fsAll; } if (fontAll >= 0) { fsThis.Font = fontAll; } // Workaround for Word 11 \f behavior. See bug 1636475. // Word 11 does not respect \f applied above the paragraph // level with \rtlpara. This is a targeted work-around // which is probably not complete, but additional repros // are currently lacking. bool isTopLevelParagraph = dnThis.Type == DocumentNodeType.dnParagraph && dnThis.Parent != null && dnThis.Parent.Type == DocumentNodeType.dnSection && dnThis.Parent.Parent == null; if (fsThis.FontSize != fsParent.FontSize) { _rtfBuilder.Append("\\fs"); _rtfBuilder.Append(fsThis.FontSize.ToString(CultureInfo.InvariantCulture)); bOutControl = true; } if (fsThis.Font != fsParent.Font || isTopLevelParagraph) { _rtfBuilder.Append("\\f"); _rtfBuilder.Append(fsThis.Font.ToString(CultureInfo.InvariantCulture)); bOutControl = true; } if (fsThis.Bold != fsParent.Bold) { _rtfBuilder.Append("\\b"); bOutControl = true; } if (fsThis.Italic != fsParent.Italic) { _rtfBuilder.Append("\\i"); bOutControl = true; } if (fsThis.UL != fsParent.UL) { _rtfBuilder.Append("\\ul"); bOutControl = true; } if (fsThis.Strike != fsParent.Strike) { _rtfBuilder.Append("\\strike"); bOutControl = true; } if (fsThis.CF != fsParent.CF) { _rtfBuilder.Append("\\cf"); _rtfBuilder.Append(fsThis.CF.ToString(CultureInfo.InvariantCulture)); bOutControl = true; } return bOutControl; }
// Token: 0x060032AD RID: 12973 RVA: 0x000E3CC8 File Offset: 0x000E1EC8 internal RtfToXamlError Next(RtfToken token, FormatState formatState) { RtfToXamlError result = RtfToXamlError.None; this._rtfLastIndex = this._rtfIndex; token.Empty(); if (this._rtfIndex >= this._rtfBytes.Length) { token.Type = RtfTokenType.TokenEOF; return(result); } int rtfIndex = this._rtfIndex; byte[] rtfBytes = this._rtfBytes; int rtfIndex2 = this._rtfIndex; this._rtfIndex = rtfIndex2 + 1; byte b = rtfBytes[rtfIndex2]; if (b <= 13) { if (b == 0) { token.Type = RtfTokenType.TokenNullChar; return(result); } if (b == 10 || b == 13) { token.Type = RtfTokenType.TokenNewline; return(result); } } else if (b != 92) { if (b == 123) { token.Type = RtfTokenType.TokenGroupStart; return(result); } if (b == 125) { token.Type = RtfTokenType.TokenGroupEnd; return(result); } } else { if (this._rtfIndex >= this._rtfBytes.Length) { token.Type = RtfTokenType.TokenInvalid; return(result); } if (this.IsControlCharValid(this.CurByte)) { int rtfIndex3 = this._rtfIndex; this.SetRtfIndex(token, rtfIndex3); token.Text = this.CurrentEncoding.GetString(this._rtfBytes, rtfIndex3 - 1, this._rtfIndex - rtfIndex); return(result); } if (this.CurByte == 39) { this._rtfIndex--; return(this.NextText(token)); } if (this.CurByte == 42) { this._rtfIndex++; token.Type = RtfTokenType.TokenDestination; return(result); } token.Type = RtfTokenType.TokenTextSymbol; token.Text = this.CurrentEncoding.GetString(this._rtfBytes, this._rtfIndex, 1); this._rtfIndex++; return(result); } this._rtfIndex--; if (formatState == null || formatState.RtfDestination != RtfDestination.DestPicture) { return(this.NextText(token)); } token.Type = RtfTokenType.TokenPictureData; return(result); }
internal void HandlePage(RtfToken token, FormatState formatState) { WrapPendingInlineInParagraph(token, formatState); }
internal void HandleOldListTokens(RtfToken token, FormatState formatState) { FormatState fsCur = _converterState.PreviousTopFormatState(0); FormatState fsOld = _converterState.PreviousTopFormatState(1); if (fsCur == null || fsOld == null) { return; } // If we're in the PN destination, we push marker setting into the previous format state. if (formatState.RtfDestination == RtfDestination.DestPN) { formatState = fsOld; } switch (token.RtfControlWordInfo.Control) { case RtfControlWord.Ctrl_PNLVL: formatState.PNLVL = token.Parameter; break; case RtfControlWord.Ctrl_PNLVLBLT: formatState.Marker = MarkerStyle.MarkerBullet; formatState.IsContinue = false; break; case RtfControlWord.Ctrl_PNLVLBODY: formatState.Marker = MarkerStyle.MarkerArabic; formatState.IsContinue = false; break; case RtfControlWord.Ctrl_PNLVLCONT: formatState.IsContinue = true; break; case RtfControlWord.Ctrl_PNCARD: formatState.Marker = MarkerStyle.MarkerCardinal; break; case RtfControlWord.Ctrl_PNDEC: formatState.Marker = MarkerStyle.MarkerArabic; break; case RtfControlWord.Ctrl_PNUCLTR: formatState.Marker = MarkerStyle.MarkerUpperAlpha; break; case RtfControlWord.Ctrl_PNUCRM: formatState.Marker = MarkerStyle.MarkerUpperRoman; break; case RtfControlWord.Ctrl_PNLCLTR: formatState.Marker = MarkerStyle.MarkerLowerAlpha; break; case RtfControlWord.Ctrl_PNLCRM: formatState.Marker = MarkerStyle.MarkerLowerRoman; break; case RtfControlWord.Ctrl_PNORD: formatState.Marker = MarkerStyle.MarkerOrdinal; break; case RtfControlWord.Ctrl_PNORDT: formatState.Marker = MarkerStyle.MarkerOrdinal; break; case RtfControlWord.Ctrl_PNBIDIA: formatState.Marker = MarkerStyle.MarkerArabic; break; case RtfControlWord.Ctrl_PNBIDIB: formatState.Marker = MarkerStyle.MarkerArabic; break; case RtfControlWord.Ctrl_PN: formatState.RtfDestination = RtfDestination.DestPN; fsOld.Marker = MarkerStyle.MarkerBullet; break; case RtfControlWord.Ctrl_PNTXTA: // Leave with unknown destination so text is tossed. break; case RtfControlWord.Ctrl_PNTXTB: // Leave with unknown destination so text is tossed. break; case RtfControlWord.Ctrl_PNTEXT: if (fsOld.IsContentDestination || formatState.IsHidden) { fsCur.RtfDestination = RtfDestination.DestListText; DocumentNodeArray dna = _converterState.DocumentNodeArray; DocumentNode dnl = new DocumentNode(DocumentNodeType.dnListText); dnl.FormatState = new FormatState(formatState); dna.Push(dnl); } break; case RtfControlWord.Ctrl_PNSTART: formatState.StartIndex = token.Parameter; break; default: formatState.Marker = MarkerStyle.MarkerBullet; break; } }
internal void HandleTableTokens(RtfToken token, FormatState formatState) { FormatState fsCur = _converterState.PreviousTopFormatState(0); FormatState fsOld = _converterState.PreviousTopFormatState(1); if (fsCur == null || fsOld == null) { return; } // Propagate current destination into nested table props destination keyword if (token.RtfControlWordInfo.Control == RtfControlWord.Ctrl_NESTTABLEPROPS) { fsCur.RtfDestination = fsOld.RtfDestination; } if (!formatState.IsContentDestination) { return; } DocumentNodeArray dna = _converterState.DocumentNodeArray; int nCellAt; bool bOldHide = formatState.IsHidden; switch (token.RtfControlWordInfo.Control) { case RtfControlWord.Ctrl_CELL: // Force a paragraph // Set intbl and itap values, then use paragraph code. formatState.IsInTable = true; formatState.ITAP = 1; formatState.IsHidden = false; HandlePara(token, formatState); formatState.IsHidden = bOldHide; nCellAt = dna.FindPending(DocumentNodeType.dnCell); if (nCellAt >= 0) { dna.CloseAt(nCellAt); // Don't coalesce cell tag itself, since I might not have yet read the properties // I need for writing out the cell attributes. // Actually, even paragraph tags inside cell needs to have table info. // dna.CoalesceOnlyChildren(_converterState, nCellAt); } break; case RtfControlWord.Ctrl_NESTCELL: // Force a paragraph out. formatState.IsHidden = false; HandlePara(token, formatState); formatState.IsHidden = bOldHide; // If we encounter an open row before an open cell, we need to open a new cell. // Or if we only have one level of table currently open. int nOpenCells = dna.CountOpenCells(); DocumentNodeType scope = dna.GetTableScope(); if (scope != DocumentNodeType.dnCell || nOpenCells < 2) { HandlePara(token, formatState); } // Now close the currently open cell nCellAt = dna.FindPending(DocumentNodeType.dnCell); if (nCellAt >= 0) { dna.CloseAt(nCellAt); // Don't coalesce cell tag itself, since I might not have yet read the properties // I need for writing out the cell attributes. // Actually, even paragraph tags inside cell needs to have table info. // dna.CoalesceOnlyChildren(_converterState, nCellAt); } break; case RtfControlWord.Ctrl_TROWD: formatState.IsHidden = false; formatState.SetRowDefaults(); formatState.IsHidden = bOldHide; break; case RtfControlWord.Ctrl_ROW: case RtfControlWord.Ctrl_NESTROW: // Word puts out \row properties both before and after the cell contents. // \nestrow properties are only put out *after* the cell contents. formatState.IsHidden = false; int nRowAt = dna.FindPending(DocumentNodeType.dnRow); if (nRowAt >= 0) { DocumentNode dnRow = dna.EntryAt(nRowAt); if (formatState.RowFormat != null) { dnRow.FormatState.RowFormat = new RowFormat(formatState.RowFormat); dnRow.FormatState.RowFormat.CanonicalizeWidthsFromRTF(); // Also cache the row information in the table node int nTable = dna.FindPendingFrom(DocumentNodeType.dnTable, nRowAt - 1, -1); if (nTable >= 0) { DocumentNode dnTable = dna.EntryAt(nTable); if (!dnTable.FormatState.HasRowFormat) { dnTable.FormatState.RowFormat = dnRow.FormatState.RowFormat; } } } // Anomalous, but possible for illegal content. ProcessPendingTextAtRowEnd(); dna.CloseAt(nRowAt); // Don't coalesce - I need to examine all cells before writing things out // dna.CoalesceChildren(_converterState, nRowAt); } formatState.IsHidden = bOldHide; break; case RtfControlWord.Ctrl_NESTTABLEPROPS: // Handled above. break; } }
internal void HandleTableProperties(RtfToken token, FormatState formatState) { if (!formatState.IsContentDestination) { return; } CellFormat cf = null; switch (token.RtfControlWordInfo.Control) { case RtfControlWord.Ctrl_TRGAPH: break; case RtfControlWord.Ctrl_TRLEFT: formatState.RowFormat.Trleft = token.Parameter; break; case RtfControlWord.Ctrl_TRQC: // Specifies overall alignment of the table row - ignore for now. break; case RtfControlWord.Ctrl_TRQL: // Specifies overall alignment of the table row - ignore for now. break; case RtfControlWord.Ctrl_TRQR: // Specifies overall alignment of the table row - ignore for now. break; case RtfControlWord.Ctrl_TRPADDL: formatState.RowFormat.RowCellFormat.PaddingLeft = token.Parameter; break; case RtfControlWord.Ctrl_TRPADDR: formatState.RowFormat.RowCellFormat.PaddingRight = token.Parameter; break; case RtfControlWord.Ctrl_TRPADDB: formatState.RowFormat.RowCellFormat.PaddingBottom = token.Parameter; break; case RtfControlWord.Ctrl_TRPADDT: formatState.RowFormat.RowCellFormat.PaddingTop = token.Parameter; break; case RtfControlWord.Ctrl_TRPADDFL: // zero value indicates ignore trpaddl, three means treat it as twips break; case RtfControlWord.Ctrl_TRPADDFT: // zero value indicates ignore trpaddt, three means treat it as twips break; case RtfControlWord.Ctrl_TRPADDFB: // zero value indicates ignore trpaddb, three means treat it as twips break; case RtfControlWord.Ctrl_TRPADDFR: // zero value indicates ignore trpaddr, three means treat it as twips break; case RtfControlWord.Ctrl_TRSPDFB: if (token.Parameter == 0) formatState.RowFormat.RowCellFormat.SpacingBottom = 0; break; case RtfControlWord.Ctrl_TRSPDFL: if (token.Parameter == 0) formatState.RowFormat.RowCellFormat.SpacingLeft = 0; break; case RtfControlWord.Ctrl_TRSPDFR: if (token.Parameter == 0) formatState.RowFormat.RowCellFormat.SpacingRight = 0; break; case RtfControlWord.Ctrl_TRSPDFT: if (token.Parameter == 0) formatState.RowFormat.RowCellFormat.SpacingTop = 0; break; case RtfControlWord.Ctrl_TRSPDB: formatState.RowFormat.RowCellFormat.SpacingBottom = token.Parameter; break; case RtfControlWord.Ctrl_TRSPDL: formatState.RowFormat.RowCellFormat.SpacingLeft = token.Parameter; break; case RtfControlWord.Ctrl_TRSPDR: formatState.RowFormat.RowCellFormat.SpacingRight = token.Parameter; break; case RtfControlWord.Ctrl_TRSPDT: formatState.RowFormat.RowCellFormat.SpacingTop = token.Parameter; break; case RtfControlWord.Ctrl_TRWWIDTH: // Row (table) width formatState.RowFormat.WidthRow.Value = token.Parameter; break; case RtfControlWord.Ctrl_TRFTSWIDTH: // Units for WWIDTH (0 - ignore, 1 - auto, 2 - 50ths of a percent, 3 - twips) if (Validators.IsValidWidthType(token.Parameter)) formatState.RowFormat.WidthRow.Type = (WidthType)token.Parameter; break; case RtfControlWord.Ctrl_TRWWIDTHB: // Space before row width break; case RtfControlWord.Ctrl_TRFTSWIDTHB: break; case RtfControlWord.Ctrl_TRWWIDTHA: // Space after row width formatState.RowFormat.WidthA.Value = token.Parameter; break; case RtfControlWord.Ctrl_TRFTSWIDTHA: if (Validators.IsValidWidthType(token.Parameter)) formatState.RowFormat.WidthA.Type = (WidthType)token.Parameter; break; case RtfControlWord.Ctrl_TRAUTOFIT: if (token.ToggleValue > 0) formatState.RowFormat.WidthRow.SetDefaults(); break; case RtfControlWord.Ctrl_CLWWIDTH: cf = formatState.RowFormat.CurrentCellFormat(); cf.Width.Value = token.Parameter; break; case RtfControlWord.Ctrl_CLFTSWIDTH: cf = formatState.RowFormat.CurrentCellFormat(); if (Validators.IsValidWidthType(token.Parameter)) cf.Width.Type = (WidthType)token.Parameter; break; case RtfControlWord.Ctrl_TRBRDRT: ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderTop; break; case RtfControlWord.Ctrl_TRBRDRB: ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderBottom; break; case RtfControlWord.Ctrl_TRBRDRR: ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderRight; break; case RtfControlWord.Ctrl_TRBRDRL: ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderLeft; break; case RtfControlWord.Ctrl_TRBRDRV: ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderLeft; break; case RtfControlWord.Ctrl_TRBRDRH: ConverterState.CurrentBorder = formatState.RowFormat.RowCellFormat.BorderTop; break; case RtfControlWord.Ctrl_CLVERTALT: cf = formatState.RowFormat.CurrentCellFormat(); cf.VAlign = VAlign.AlignTop; break; case RtfControlWord.Ctrl_CLVERTALB: cf = formatState.RowFormat.CurrentCellFormat(); cf.VAlign = VAlign.AlignBottom; break; case RtfControlWord.Ctrl_CLVERTALC: cf = formatState.RowFormat.CurrentCellFormat(); cf.VAlign = VAlign.AlignCenter; break; case RtfControlWord.Ctrl_CLSHDNG: // Cell shading in 100's of a percent cf = formatState.RowFormat.CurrentCellFormat(); cf.Shading = token.Parameter; break; case RtfControlWord.Ctrl_CLSHDRAWNIL: // No cell shading - clear color for now cf = formatState.RowFormat.CurrentCellFormat(); cf.Shading = -1; cf.CB = -1; cf.CF = -1; break; case RtfControlWord.Ctrl_CLBRDRB: cf = formatState.RowFormat.CurrentCellFormat(); ConverterState.CurrentBorder = cf.BorderBottom; break; case RtfControlWord.Ctrl_CLBRDRR: cf = formatState.RowFormat.CurrentCellFormat(); ConverterState.CurrentBorder = cf.BorderRight; break; case RtfControlWord.Ctrl_CLBRDRT: cf = formatState.RowFormat.CurrentCellFormat(); ConverterState.CurrentBorder = cf.BorderTop; break; case RtfControlWord.Ctrl_CLBRDRL: cf = formatState.RowFormat.CurrentCellFormat(); ConverterState.CurrentBorder = cf.BorderLeft; break; case RtfControlWord.Ctrl_CLCBPAT: cf = formatState.RowFormat.CurrentCellFormat(); cf.CB = token.Parameter; break; case RtfControlWord.Ctrl_CLCFPAT: cf = formatState.RowFormat.CurrentCellFormat(); cf.CF = token.Parameter; break; case RtfControlWord.Ctrl_CLPADL: cf = formatState.RowFormat.CurrentCellFormat(); cf.PaddingLeft = token.Parameter; break; case RtfControlWord.Ctrl_CLPADR: cf = formatState.RowFormat.CurrentCellFormat(); cf.PaddingRight = token.Parameter; break; case RtfControlWord.Ctrl_CLPADB: cf = formatState.RowFormat.CurrentCellFormat(); cf.PaddingBottom = token.Parameter; break; case RtfControlWord.Ctrl_CLPADT: cf = formatState.RowFormat.CurrentCellFormat(); cf.PaddingTop = token.Parameter; break; case RtfControlWord.Ctrl_CLPADFL: // zero value indicates ignore clpadl, three means treat it as twips break; case RtfControlWord.Ctrl_CLPADFT: // zero value indicates ignore clpadt, three means treat it as twips break; case RtfControlWord.Ctrl_CLPADFB: // zero value indicates ignore clpadb, three means treat it as twips break; case RtfControlWord.Ctrl_CLPADFR: // zero value indicates ignore clpadr, three means treat it as twips break; case RtfControlWord.Ctrl_CELLX: cf = formatState.RowFormat.CurrentCellFormat(); cf.CellX = token.Parameter; cf.IsPending = false; break; case RtfControlWord.Ctrl_RTLROW: formatState.RowFormat.Dir = DirState.DirRTL; break; case RtfControlWord.Ctrl_LTRROW: formatState.RowFormat.Dir = DirState.DirLTR; break; // Cell merging case RtfControlWord.Ctrl_CLMGF: // First cell in range of table cells to be merged. cf = formatState.RowFormat.CurrentCellFormat(); cf.IsHMergeFirst = true; break; case RtfControlWord.Ctrl_CLMRG: // Contents of this cell are merged with those of the preceding cell. cf = formatState.RowFormat.CurrentCellFormat(); cf.IsHMerge = true; break; case RtfControlWord.Ctrl_CLVMGF: // First cell in range of cells to be vertically merged. cf = formatState.RowFormat.CurrentCellFormat(); cf.IsVMergeFirst = true; break; case RtfControlWord.Ctrl_CLVMRG: // Contents of this cell are vertically merged with those of the preceding cell. cf = formatState.RowFormat.CurrentCellFormat(); cf.IsVMerge = true; break; // General borders, not just tables case RtfControlWord.Ctrl_BRDRL: // Left paragraph border ConverterState.CurrentBorder = formatState.ParaBorder.BorderLeft; break; case RtfControlWord.Ctrl_BRDRR: // Right paragraph border ConverterState.CurrentBorder = formatState.ParaBorder.BorderRight; break; case RtfControlWord.Ctrl_BRDRT: // Top paragraph border ConverterState.CurrentBorder = formatState.ParaBorder.BorderTop; break; case RtfControlWord.Ctrl_BRDRB: // Bottom paragraph border ConverterState.CurrentBorder = formatState.ParaBorder.BorderBottom; break; case RtfControlWord.Ctrl_BOX: // All four borders ConverterState.CurrentBorder = formatState.ParaBorder.BorderAll; break; case RtfControlWord.Ctrl_BRDRNIL: // No borders ConverterState.CurrentBorder = null; break; case RtfControlWord.Ctrl_BRSP: // Space in twips between borders and paragraph formatState.ParaBorder.Spacing = token.Parameter; break; case RtfControlWord.Ctrl_BRDRTBL: // No cell borders if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderNone; } break; case RtfControlWord.Ctrl_BRDRART: // Art border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRBAR: // Border on outside edge of page (treat as BRDRL for XAML) break; case RtfControlWord.Ctrl_BRDRBTW: break; case RtfControlWord.Ctrl_BRDRCF: if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.CF = token.Parameter; } break; case RtfControlWord.Ctrl_BRDRDASH: // Dashed border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRDASHD: // Dash dot border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRDASHDD: // Dot dot dash border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRDASHDOTSTR: // Dash-dot border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRDASHSM: // Small dash border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRDB: // Double border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderDouble; } break; case RtfControlWord.Ctrl_BRDRDOT: // Dotted border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDREMBOSS: // Emboss-style border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRENGRAVE: // Engrave-style border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRFRAME: // Frame-style border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRHAIR: // Hairline border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRINSET: // Inset border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDROUTSET: // Outset border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRS: if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRSH: // Shadow border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRTH: if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderDouble; } break; case RtfControlWord.Ctrl_BRDRTHTNLG: // Thick-thin (large) border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRTHTNMG: // Thick-thin (medium) border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRTHTNSG: // Thick-thin-thin (thin) border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRTNTHLG: // Thin-thick (large) border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRTNTHMG: // Thick-thin-thin (medium) border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRTNTHSG: // Thick-thin-thin (small) border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRTNTHTNLG: // Thick-thin-thin (large) border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRTNTHTNMG: // Thin-thick-thin (medium) border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRTNTHTNSG: // Thick-thin-thin (small) border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRTRIPLE: // Triple border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRW: // Border thickness if (ConverterState.CurrentBorder != null) { // Note that propset does validation ConverterState.CurrentBorder.Width = token.Parameter; } break; case RtfControlWord.Ctrl_BRDRNONE: // No borders if (ConverterState.CurrentBorder != null) { // Note that propset does validation ConverterState.CurrentBorder.SetDefaults(); } break; case RtfControlWord.Ctrl_BRDRWAVY: // Wavy border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderSingle; } break; case RtfControlWord.Ctrl_BRDRWAVYDB: // Double border if (ConverterState.CurrentBorder != null) { ConverterState.CurrentBorder.Type = BorderType.BorderDouble; } break; } }
internal void ProcessHardLine(RtfToken token, FormatState formatState) { switch (_converterState.TopFormatState.RtfDestination) { case RtfDestination.DestNormal: case RtfDestination.DestFieldResult: case RtfDestination.DestShapeResult: case RtfDestination.DestListText: ProcessNormalHardLine(formatState); break; case RtfDestination.DestFontTable: case RtfDestination.DestFontName: break; case RtfDestination.DestColorTable: break; case RtfDestination.DestField: break; case RtfDestination.DestFieldInstruction: case RtfDestination.DestFieldPrivate: ProcessNormalHardLine(formatState); break; } }
internal void HandleFieldTokens(RtfToken token, FormatState formatState) { // Don't start processing fields in non-normal destinatations FormatState fsCur = _converterState.PreviousTopFormatState(0); FormatState fsOld = _converterState.PreviousTopFormatState(1); if (fsCur == null || fsOld == null) { return; } switch (token.RtfControlWordInfo.Control) { case RtfControlWord.Ctrl_FIELD: // Process fields in normal content or nested fields if (!fsOld.IsContentDestination || formatState.IsHidden) { return; } formatState.RtfDestination = RtfDestination.DestField; break; case RtfControlWord.Ctrl_FLDRSLT: if (fsOld.RtfDestination != RtfDestination.DestField) { return; } formatState.RtfDestination = RtfDestination.DestFieldResult; break; case RtfControlWord.Ctrl_FLDPRIV: if (fsOld.RtfDestination != RtfDestination.DestField) { return; } formatState.RtfDestination = RtfDestination.DestFieldPrivate; break; case RtfControlWord.Ctrl_FLDINST: if (fsOld.RtfDestination != RtfDestination.DestField) { return; } formatState.RtfDestination = RtfDestination.DestFieldInstruction; break; default: return; } DocumentNodeArray dna = _converterState.DocumentNodeArray; DocumentNode dnf = new DocumentNode(DocumentNodeType.dnFieldBegin); dnf.FormatState = new FormatState(formatState); dnf.IsPending = false; // Field start mark should not impact other tags open/close behavior dnf.IsTerminated = true; dna.Push(dnf); }
private void EnsureListAndListItem(FormatState formatState, DocumentNodeArray dna, MarkerList mlHave, MarkerList mlWant, int nMatch) { int nInsertAt; bool added = false; int nLists = mlHave.Count; int nLevel = mlWant.Count; // Close any open lists that don't match the ones we want. bool bInField = dna.FindUnmatched(DocumentNodeType.dnFieldBegin) >= 0; if (nLists > nMatch) { DocumentNode documentNodePara = dna.Pop(); while (nLists > nMatch) { int nOpen = dna.FindPending(DocumentNodeType.dnList); if (nOpen >= 0) { dna.CloseAt(nOpen); // Only coalesce if this is a top-level list. Otherwise I want to get // the full structure to use for margin fixups so I delay coalescing. // No, don't coalesce since a later list may need to get merged with this one. // if (!bInField && dna.FindPending(DocumentNodeType.dnList) < 0) // dna.CoalesceChildren(_converterState, nOpen); } nLists--; mlHave.RemoveRange(mlHave.Count - 1, 1); } dna.Push(documentNodePara); } if (nLists < nLevel) { // Multiple immediately nested lists are handled poorly in Avalon and are usually an indication // of bad input from Word (or some other word processor). Clip the number of lists we'll create here. if (nLevel != nLists + 1) { // I'm going to truncate, but make the list I create here of the specific type at this level. if (nLevel <= mlWant.Count) { mlWant[nLists] = mlWant[mlWant.Count - 1]; } nLevel = nLists + 1; } // Ensure sufficient lists are open - this may be our first indication // Insert the list nodes right before the current paragraph nInsertAt = dna.Count - 1; while (nLists < nLevel) { added = true; DocumentNode dnList = new DocumentNode(DocumentNodeType.dnList); DocumentNode dnLI = new DocumentNode(DocumentNodeType.dnListItem); dna.InsertNode(nInsertAt, dnLI); dna.InsertNode(nInsertAt, dnList); // Set the list properties MarkerListEntry mle = mlWant.EntryAt(nLists); dnList.FormatState.Marker = mle.Marker; dnList.FormatState.StartIndex = mle.StartIndexToUse; dnList.FormatState.StartIndexDefault = mle.StartIndexDefault; dnList.VirtualListLevel = mle.VirtualListLevel; dnList.FormatState.ILS = mle.ILS; nLists++; } } // Ensure listitem is open nInsertAt = dna.Count - 1; int nList = dna.FindPending(DocumentNodeType.dnList); if (nList >= 0) { int nLI = dna.FindPending(DocumentNodeType.dnListItem, nList); if (nLI >= 0 && !added && !formatState.IsContinue) { DocumentNode documentNodePara = dna.Pop(); dna.CloseAt(nLI); // Don't coalesce - I may need to do margin fixup. // dna.CoalesceChildren(_converterState, nLI); dna.Push(documentNodePara); nLI = -1; nInsertAt = dna.Count - 1; } if (nLI == -1) { DocumentNode dnLI = new DocumentNode(DocumentNodeType.dnListItem); dna.InsertNode(nInsertAt, dnLI); } } }
internal void HandleTableNesting(FormatState formatState) { DocumentNodeArray dna = _converterState.DocumentNodeArray; // If we're in a throw-away destination, just return. if (!formatState.IsContentDestination || formatState.IsHidden) { return; } // Make sure proper number of tables are open to reflect this paragraphs nest level int nTables = dna.CountOpenNodes(DocumentNodeType.dnTable); int nLevel = (int)formatState.TableLevel; // If we're not in a table, end early if (nTables == nLevel && nTables == 0) { return; } if (nTables > nLevel) { DocumentNode dnPara = dna.Pop(); bool bInField = dna.FindUnmatched(DocumentNodeType.dnFieldBegin) >= 0; while (nTables > nLevel) { int nOpen = dna.FindPending(DocumentNodeType.dnTable); if (nOpen >= 0) { dna.CloseAt(nOpen); if (!bInField) { dna.CoalesceChildren(_converterState, nOpen); } } nTables--; } dna.Push(dnPara); } else { // Before opening the table, let's close any open lists. Word (RTF) allows somewhat // arbitrary interleaving (because there's no explicit nesting), but when converting to // XAML we have to choose an explicit nesting. We never create a table *inside* a list, so // let's just terminate any open lists right now. if (nTables < nLevel) { int nListAt = dna.FindPending(DocumentNodeType.dnList); if (nListAt >= 0) { // I want the currently pending paragraph to be part of the table, not part of the list // I'm going to close. So I temporarily pop it off while closing off the list and then // push it back on before inserting the table(s). DocumentNode dnPara = dna.Pop(); while (nListAt >= 0) { dna.CloseAt(nListAt); nListAt = dna.FindPending(DocumentNodeType.dnList); } dna.Push(dnPara); } } // Ensure sufficient tables are open - this may be our first indication // Insert the table nodes right before the current paragraph. Debug.Assert(dna.Count > 0 && dna.EntryAt(dna.Count - 1).Type == DocumentNodeType.dnParagraph); int nInsertAt = dna.Count - 1; // Ensure row is open int nTable = dna.FindPending(DocumentNodeType.dnTable); if (nTable >= 0) { int nRow = dna.FindPending(DocumentNodeType.dnRow, nTable); if (nRow == -1) { DocumentNode dnRow = new DocumentNode(DocumentNodeType.dnRow); dna.InsertNode(nInsertAt++, dnRow); nRow = nInsertAt - 1; } int nCell = dna.FindPending(DocumentNodeType.dnCell, nRow); if (nCell == -1) { DocumentNode dnCell = new DocumentNode(DocumentNodeType.dnCell); dna.InsertNode(nInsertAt, dnCell); } } nInsertAt = dna.Count - 1; while (nTables < nLevel) { DocumentNode dnTable = new DocumentNode(DocumentNodeType.dnTable); DocumentNode dnTableBody = new DocumentNode(DocumentNodeType.dnTableBody); DocumentNode dnRow = new DocumentNode(DocumentNodeType.dnRow); DocumentNode dnCell = new DocumentNode(DocumentNodeType.dnCell); dna.InsertNode(nInsertAt, dnCell); dna.InsertNode(nInsertAt, dnRow); dna.InsertNode(nInsertAt, dnTableBody); dna.InsertNode(nInsertAt, dnTable); nTables++; } } dna.AssertTreeSemanticInvariants(); }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods internal void InheritFormatState(FormatState formatState) { _formatState = new FormatState(formatState); // Reset non-inherited properties _formatState.LI = 0; _formatState.RI = 0; _formatState.SB = 0; _formatState.SA = 0; _formatState.FI = 0; _formatState.Marker = MarkerStyle.MarkerNone; _formatState.CBPara = -1; }
internal MarkerList GetMarkerStylesOfParagraph(MarkerList mlHave, FormatState fs, bool bMarkerPresent) { MarkerList mlWant = new MarkerList(); long nVirtualListLevel = fs.ListLevel; long nStartIndexOverride = -1; // No list? if (nVirtualListLevel < 1) { return mlWant; } // Use currently open list styles for all levels below requested one for (int i = 0; i < mlHave.Count; i++) if (mlHave.EntryAt(i).VirtualListLevel < nVirtualListLevel || fs.IsContinue) { MarkerListEntry mle = mlHave.EntryAt(i); mlWant.AddEntry(mle.Marker, mle.ILS, -1, mle.StartIndexDefault, mle.VirtualListLevel); } else { break; } // If I'm a continuation paragraph, I'm done. if (fs.IsContinue) { return mlWant; } // Now determine the list style for the list level I'm going to add. ListOverrideTable lot = _converterState.ListOverrideTable; ListOverride lo = lot.FindEntry((int)fs.ILS); if (lo != null) { ListLevelTable levels = lo.Levels; if (levels == null || levels.Count == 0) { ListTableEntry lte = _converterState.ListTable.FindEntry(lo.ID); if (lte != null) { levels = lte.Levels; } // Did the list override specify a start index? if (lo.StartIndex > 0) { nStartIndexOverride = lo.StartIndex; } } if (levels != null) { ListLevel listLevel = levels.EntryAt((int)nVirtualListLevel - 1); if (listLevel != null) { // If there was a marker present, we ignore the "Hidden" style in the list table. MarkerStyle ms = listLevel.Marker; if (ms == MarkerStyle.MarkerHidden && bMarkerPresent) { ms = MarkerStyle.MarkerBullet; } mlWant.AddEntry(ms, fs.ILS, nStartIndexOverride, listLevel.StartIndex, nVirtualListLevel); return mlWant; } } } // If there wasn't a list definition, use the marker type in the formatstate. mlWant.AddEntry(fs.Marker, fs.ILS, nStartIndexOverride, fs.StartIndex, nVirtualListLevel); return mlWant; }
internal FormatState(FormatState formatState) { // Font settings Bold = formatState.Bold; Italic = formatState.Italic; Engrave = formatState.Engrave; Shadow = formatState.Shadow; SCaps = formatState.SCaps; Outline = formatState.Outline; Super = formatState.Super; Sub = formatState.Sub; SuperOffset = formatState.SuperOffset; FontSize = formatState.FontSize; Font = formatState.Font; CodePage = formatState.CodePage; CF = formatState.CF; CB = formatState.CB; DirChar = formatState.DirChar; UL = formatState.UL; Strike = formatState.Strike; Expand = formatState.Expand; Lang = formatState.Lang; LangFE = formatState.LangFE; LangCur = formatState.LangCur; FontSlot = formatState.FontSlot; // Para settings SB = formatState.SB; SA = formatState.SA; FI = formatState.FI; RI = formatState.RI; LI = formatState.LI; SL = formatState.SL; SLMult = formatState.SLMult; HAlign = formatState.HAlign; ILVL = formatState.ILVL; ITAP = formatState.ITAP; ILS = formatState.ILS; DirPara = formatState.DirPara; CFPara = formatState.CFPara; CBPara = formatState.CBPara; ParaShading = formatState.ParaShading; Marker = formatState.Marker; IsContinue = formatState.IsContinue; StartIndex = formatState.StartIndex; StartIndexDefault = formatState.StartIndexDefault; IsInTable = formatState.IsInTable; _pb = formatState.HasParaBorder ? new ParaBorder(formatState.ParaBorder) : null; // Row settings // For performance reasons, we don't make a full copy of the Row format information. The implication // of this is that changes to row format data will propagate back up from nested scopes, which is not // according to the strict semantics. But in practice, all new rows are explicitly cleared with the // \trowd keyword, which clears this, so this should be fine. RowFormat = formatState._rowFormat; // Other RtfDestination = formatState.RtfDestination; IsHidden = formatState.IsHidden; _stateSkip = formatState.UnicodeSkip; }
internal void HandleListNesting(FormatState formatState) { DocumentNodeArray dna = _converterState.DocumentNodeArray; DocumentNode dnPara = dna.EntryAt(dna.Count - 1); bool bMarkerPresent = _converterState.IsMarkerPresent; // Test if we encountered list text if (_converterState.IsMarkerPresent) { _converterState.IsMarkerPresent = false; } // If we're in a throw-away destination, just return. if (!formatState.IsContentDestination || formatState.IsHidden) { return; } // Treat no marker text present as a continuation paragraph if (!bMarkerPresent && formatState.ListLevel > 0) { // Allocate a new one here so that this change doesn't propagate beyond here. formatState = new FormatState(formatState); // If the only thing making this look like a list is the ILVL property, just clear it. if (formatState.ILVL > 0 && formatState.ILS < 0) { formatState.ILVL = 0; } else // otherwise treat this as a continuation paragraph. { formatState.IsContinue = true; } } // Make sure proper number of lists are open to reflect this paragraphs nest level MarkerList mlHave = dna.GetOpenMarkerStyles(); MarkerList mlWant = GetMarkerStylesOfParagraph(mlHave, formatState, bMarkerPresent); int nLists = mlHave.Count; int nLevel = mlWant.Count; // If we're not in a list end early if (nLists == nLevel && nLists == 0) { return; } // If we're not in a list and marked as a continuation, ignore this - anomaly. if (nLists == 0 && nLevel == 1 && formatState.IsContinue) { return; } // Propagate noticing that the specified text was empty. if (_converterState.IsMarkerWhiteSpace) { _converterState.IsMarkerWhiteSpace = false; if (nLevel > 0) { MarkerListEntry entry = mlWant.EntryAt(nLevel - 1); entry.Marker = MarkerStyle.MarkerHidden; } } // The ones we have are only "good" if the styles match what we want. int nMatch = GetMatchedMarkList(formatState, mlHave, mlWant); // If none match, we might do better by extending some previously open list. if (nMatch == 0) { MarkerList mlCouldHave = dna.GetLastMarkerStyles(mlHave, mlWant); MarkerList mlCouldWant = GetMarkerStylesOfParagraph(mlCouldHave, formatState, bMarkerPresent); nMatch = GetMatchedMarkList(formatState, mlCouldHave, mlCouldWant); // If I would re-open a previous list but close some set of them and then reopen another, // this is unlikely to be what the user intended. Instead, don't extend the previous list. // See Windows OS Bugs: 1373731. if (nMatch < mlCouldHave.Count && mlCouldWant.Count > nMatch) { nMatch = 0; } if (nMatch > 0) { mlHave = mlCouldHave; mlWant = mlCouldWant; dna.OpenLastList(); } } // Ensure list and listitem EnsureListAndListItem(formatState, dna, mlHave, mlWant, nMatch); // To get better results in XAML output, clear the FI for the first para in a list item. if (dna.Count > 1 && dna.EntryAt(dna.Count - 2).Type == DocumentNodeType.dnListItem) { Debug.Assert(!dnPara.IsTerminated); dnPara.FormatState.FI = 0; } dna.AssertTreeSemanticInvariants(); }
internal bool IsEqual(FormatState formatState) { return // Font Settings Bold == formatState.Bold && Italic == formatState.Italic && Engrave == formatState.Engrave && Shadow == formatState.Shadow && SCaps == formatState.SCaps && Outline == formatState.Outline && Super == formatState.Super && Sub == formatState.Sub && SuperOffset == formatState.SuperOffset && FontSize == formatState.FontSize && Font == formatState.Font && CodePage == formatState.CodePage && CF == formatState.CF && CB == formatState.CB && DirChar == formatState.DirChar && UL == formatState.UL && Strike == formatState.Strike && Expand == formatState.Expand && Lang == formatState.Lang && LangFE == formatState.LangFE && LangCur == formatState.LangCur && FontSlot == formatState.FontSlot // Para settings && SB == formatState.SB && SA == formatState.SA && FI == formatState.FI && RI == formatState.RI && LI == formatState.LI && HAlign == formatState.HAlign && ILVL == formatState.ILVL && ITAP == formatState.ITAP && ILS == formatState.ILS && DirPara == formatState.DirPara && CFPara == formatState.CFPara && CBPara == formatState.CBPara && ParaShading == formatState.ParaShading && Marker == formatState.Marker && IsContinue == formatState.IsContinue && StartIndex == formatState.StartIndex && StartIndexDefault == formatState.StartIndexDefault && SL == formatState.SL && SLMult == formatState.SLMult && IsInTable == formatState.IsInTable // Don't include para borders in this test // Row Settings // Don't include row settings in this test. // Other && RtfDestination == formatState.RtfDestination && IsHidden == formatState.IsHidden && UnicodeSkip == formatState.UnicodeSkip; }
internal void HandleCodePageTokens(RtfToken token, FormatState formatState) { switch (token.RtfControlWordInfo.Control) { case RtfControlWord.Ctrl_ANSI: // ANSI apparently means specifically 1252, not ACP. That makes a lot more sense... //_converterState.CodePage = CultureInfo.CurrentCulture.TextInfo.ANSICodePage; _converterState.CodePage = 1252; _lexer.CodePage = _converterState.CodePage; break; case RtfControlWord.Ctrl_MAC: _converterState.CodePage = 10000; _lexer.CodePage = _converterState.CodePage; break; case RtfControlWord.Ctrl_PC: _converterState.CodePage = 437; _lexer.CodePage = _converterState.CodePage; break; case RtfControlWord.Ctrl_PCA: _converterState.CodePage = 850; _lexer.CodePage = _converterState.CodePage; break; case RtfControlWord.Ctrl_UPR: // We discard this ansi representation - \ud will then switch back to current. formatState.RtfDestination = RtfDestination.DestUPR; break; case RtfControlWord.Ctrl_U: { char[] unicodeChar = new char[1]; unicodeChar[0] = (char)token.Parameter; ProcessText(new string(unicodeChar)); } break; case RtfControlWord.Ctrl_UD: { // We are parsing: {\upr ansi stuff{\*\ud unicode stuff }} // When we encountered the UPR we set state to a throwaway destination (DestUPR). // The nested group pushed a new format state but that now has DestUnknown because of this. // Now that we encountered the \ud destination, lets push back the original destination. FormatState previous = _converterState.PreviousTopFormatState(1); FormatState previousPrevious = _converterState.PreviousTopFormatState(2); if (previous != null && previousPrevious != null) { if (formatState.RtfDestination == RtfDestination.DestUPR && previous.RtfDestination == RtfDestination.DestUnknown) { formatState.RtfDestination = previousPrevious.RtfDestination; } } } break; case RtfControlWord.Ctrl_UC: formatState.UnicodeSkip = (int)token.Parameter; break; } }
internal void HandleBinControl(RtfToken token, FormatState formatState) { if (token.Parameter > 0) { if (formatState.RtfDestination == RtfDestination.DestPicture) { formatState.IsImageDataBinary = true; } else { _lexer.AdvanceForBinary((int)token.Parameter); } } }
internal void HandleNormalText(string text, FormatState formatState) { // Normal CRLF's are eaten by the RTF lexer. Any ones that have slipped through here // were either escaped or hex-encoded and should be treated as a linebreak. int nStart = 0; while (nStart < text.Length) { int nEnd = nStart; while (nEnd < text.Length) { if (text[nEnd] == 0x0d || text[nEnd] == 0x0a) { break; } nEnd++; } // Handle text before newline if (nStart == 0 && nEnd == text.Length) { HandleNormalTextRaw(text, formatState); } else if (nEnd > nStart) { string subtext = text.Substring(nStart, nEnd - nStart); HandleNormalTextRaw(subtext, formatState); } // Handle newlines while (nEnd < text.Length && (text[nEnd] == 0x0d || text[nEnd] == 0x0a)) { ProcessNormalHardLine(formatState); if (nEnd + 1 < text.Length && text[nEnd] == 0x0d && text[nEnd] == 0x0a) { nEnd += 2; } else { nEnd += 1; } } nStart = nEnd; } }
internal void WrapPendingInlineInParagraph(RtfToken token, FormatState formatState) { // Ignore \par in other destinations if (!formatState.IsContentDestination || formatState.IsHidden) { return; } // Only treat \page as \par if there is already some inline content. In normal cases, // (e.g. Word output) a page break comes between paragraphs and we don't want to emit // anything extra in that case. DocumentNodeArray dna = _converterState.DocumentNodeArray; DocumentNode dn; // Insert the paragraph before any text or inline nodes at the top of the stack. int nNoOpValue = dna.Count; int nInsertAt = dna.Count; // Default insertion location for (; nInsertAt > 0; nInsertAt--) { dn = dna.EntryAt(nInsertAt - 1); if (!dn.IsInline || dn.ClosedParent != null || !dn.IsMatched) { break; } // If we only have listtext on the stack, don't force a para. else if (dn.Type == DocumentNodeType.dnListText && !dn.IsPending && nInsertAt + dn.ChildCount == dna.Count) { nNoOpValue = nInsertAt - 1; } } // If there are no inline nodes, don't generate extra content. if (nInsertAt == nNoOpValue) { return; } // Otherwise, just treat as paragraph mark HandlePara(token, formatState); }
internal void HandleNormalTextRaw(string text, FormatState formatState) { DocumentNodeArray dna = _converterState.DocumentNodeArray; DocumentNode dnTop = dna.Top; // See if I can just append the text content if the format is the same. if (dnTop != null && (dnTop.Type == DocumentNodeType.dnText)) { // If the format is not equal, close this text element and we'll open a new one. if (!dnTop.FormatState.IsEqual(formatState)) { dna.CloseAt(dna.Count - 1); dnTop = null; } } // OK, create a text node if necessary if (dnTop == null || dnTop.Type != DocumentNodeType.dnText) { dnTop = new DocumentNode(DocumentNodeType.dnText); dnTop.FormatState = new FormatState(formatState); dna.Push(dnTop); } Debug.Assert(!dnTop.IsTerminated); dnTop.AppendXamlEncoded(text); dnTop.IsPending = false; }
internal void HandleParagraphFromText(FormatState formatState) { DocumentNodeArray dna = _converterState.DocumentNodeArray; DocumentNode dn; // Insert the paragraph before any text or inline nodes at the top of the stack. int nInsertAt = dna.Count; // Default insertion location for (; nInsertAt > 0; nInsertAt--) { dn = dna.EntryAt(nInsertAt - 1); if (!dn.IsInline || (dn.ClosedParent != null && !dn.ClosedParent.IsInline) || !dn.IsMatched) { break; } } dn = new DocumentNode(DocumentNodeType.dnParagraph); dn.FormatState = new FormatState(formatState); dn.ConstrainFontPropagation(formatState); dna.InsertNode(nInsertAt, dn); // Now close immediately. dna.CloseAt(nInsertAt); dna.CoalesceOnlyChildren(_converterState, nInsertAt); }
internal void ProcessNormalHardLine(FormatState formatState) { // Close out pending text nodes DocumentNodeArray dna = _converterState.DocumentNodeArray; if (dna.TestTop(DocumentNodeType.dnText)) { dna.CloseAt(dna.Count - 1); } DocumentNode documentNode = new DocumentNode(DocumentNodeType.dnLineBreak); documentNode.FormatState = new FormatState(formatState); dna.Push(documentNode); dna.CloseAt(dna.Count - 1); dna.CoalesceChildren(_converterState, dna.Count - 1); }
//------------------------------------------------------ // // 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); }
// Token: 0x060032DF RID: 13023 RVA: 0x000E5564 File Offset: 0x000E3764 internal bool IsEqual(FormatState formatState) { return(this.Bold == formatState.Bold && this.Italic == formatState.Italic && this.Engrave == formatState.Engrave && this.Shadow == formatState.Shadow && this.SCaps == formatState.SCaps && this.Outline == formatState.Outline && this.Super == formatState.Super && this.Sub == formatState.Sub && this.SuperOffset == formatState.SuperOffset && this.FontSize == formatState.FontSize && this.Font == formatState.Font && this.CodePage == formatState.CodePage && this.CF == formatState.CF && this.CB == formatState.CB && this.DirChar == formatState.DirChar && this.UL == formatState.UL && this.Strike == formatState.Strike && this.Expand == formatState.Expand && this.Lang == formatState.Lang && this.LangFE == formatState.LangFE && this.LangCur == formatState.LangCur && this.FontSlot == formatState.FontSlot && this.SB == formatState.SB && this.SA == formatState.SA && this.FI == formatState.FI && this.RI == formatState.RI && this.LI == formatState.LI && this.HAlign == formatState.HAlign && this.ILVL == formatState.ILVL && this.ITAP == formatState.ITAP && this.ILS == formatState.ILS && this.DirPara == formatState.DirPara && this.CFPara == formatState.CFPara && this.CBPara == formatState.CBPara && this.ParaShading == formatState.ParaShading && this.Marker == formatState.Marker && this.IsContinue == formatState.IsContinue && this.StartIndex == formatState.StartIndex && this.StartIndexDefault == formatState.StartIndexDefault && this.SL == formatState.SL && this.SLMult == formatState.SLMult && this.IsInTable == formatState.IsInTable && this.RtfDestination == formatState.RtfDestination && this.IsHidden == formatState.IsHidden && this.UnicodeSkip == formatState.UnicodeSkip); }