Ejemplo n.º 1
0
		private static void ProcessClauseContent(XmlWriter writer, XmlNodeList nodeList, PdfLayoutSettings pdfLayoutSettings, Stack<PdfStyle> styleStack)
		{
			foreach (XmlNode node in nodeList)
			{
				switch (node.NodeType)
				{
					#region NodeType == Element
					case XmlNodeType.Element:
						{
							switch (node.Name)
							{
								#region case font
								case "font":
									{
										styleStack.Push(GetStyleFromFontElement(node, styleStack.Peek()));
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										styleStack.Pop();
										break;
									}
								#endregion

								#region case b/strong
								case "strong":
								case "b":
									{
										PdfStyle newStyle = new PdfStyle();
										newStyle.CopyFrom(styleStack.Peek());
										newStyle.Font.Bold = true;
										styleStack.Push(newStyle);
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										styleStack.Pop();
										break;
									}
								#endregion

                                #region case pws    
                                case Term._ELEMENT_PRESERVE_WHITE_SPACE:
                                    {
                                        PdfStyle newStyle = new PdfStyle();
                                        newStyle.CopyFrom(styleStack.Peek());
                                        newStyle.PreserveWhiteSpace = true;
                                        styleStack.Push(newStyle);
                                        ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
                                        styleStack.Pop();
                                        break;
                                    }
                                #endregion

								#region case sup
								case "sup":
									{
										PdfStyle newStyle = new PdfStyle();
										newStyle.CopyFrom(styleStack.Peek());
										newStyle.FontTransform = FontTransform.Superscript;
										styleStack.Push(newStyle);
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										styleStack.Pop();
										break;
									}
								#endregion

								#region case sub
								case "sub":
									{
										PdfStyle newStyle = new PdfStyle();
										newStyle.CopyFrom(styleStack.Peek());
										newStyle.FontTransform = FontTransform.Subscript;
										styleStack.Push(newStyle);
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										styleStack.Pop();
										break;
									}
								#endregion

								#region case i/em
								case "i":
								case "em":
									{
										PdfStyle newStyle = new PdfStyle();
										newStyle.CopyFrom(styleStack.Peek());
										newStyle.Font.Italic = true;
										styleStack.Push(newStyle);
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										styleStack.Pop();
										break;
									}
								#endregion

								#region case u, a
								//treat <a></a>  just like <u></u> when rendering a PDF
								case "a":
								case "u":
									{
										PdfStyle newStyle = new PdfStyle();
										newStyle.CopyFrom(styleStack.Peek());
										newStyle.Font.Underline = true;
										styleStack.Push(newStyle);
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										styleStack.Pop();
										break;
									}
								#endregion

								#region case strike
								case "strike":
									{
										PdfStyle newStyle = new PdfStyle();
										newStyle.CopyFrom(styleStack.Peek());
										newStyle.Font.Strikeout = true;
										styleStack.Push(newStyle);
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										styleStack.Pop();
										break;
									}
								#endregion

								#region case span
								case "span":
									{
										XmlAttribute attrSpanStyle = node.Attributes["style"];
										if (attrSpanStyle != null)
											styleStack.Push(GetStyleFromStyleAttribute(attrSpanStyle, styleStack.Peek()));
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										if (attrSpanStyle != null)
											styleStack.Pop();
										break;
									}
								#endregion

								#region case div
								case "div":
									{
										XmlAttribute attrDivStyle = node.Attributes["style"];
										if (attrDivStyle != null)
											styleStack.Push(GetStyleFromStyleAttribute(attrDivStyle, styleStack.Peek()));
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										if (attrDivStyle != null)
											styleStack.Pop();
										WriteLineBreak(writer, true);
										break;
									}
								#endregion

								#region case br
								case "br":
									{
										WriteLineBreak(writer, pdfLayoutSettings.OpenParagraphCounter <= 0);
										break;
									}
								#endregion

								#region case  p
								case "p":
									{
										if (ContainsImage(node))
										{
											ProcessImage(writer, pdfLayoutSettings, node);
										}
										else
										{
											if (pdfLayoutSettings.OpenParagraphCounter > 0)
											{
												writer.WriteEndElement();  //close current paragraph before starting a new one
												pdfLayoutSettings.OpenParagraphCounter--;
											}
											if (node.ChildNodes.Count > 0)
											{
												writer.WriteStartElement("paragraph");
												pdfLayoutSettings.InTextParagraph = true;
												pdfLayoutSettings.OpenParagraphCounter++;
												pdfLayoutSettings.ParagraphAlignment = GetParagraphAlignment(node);
												writer.WriteAttributeString("spacingbefore", (pdfLayoutSettings.SuppressSpacingBefore ? "0" : PARAGRAPH_SPACING.ToString()));
												if (!string.IsNullOrEmpty(pdfLayoutSettings.ParagraphAlignment.Key))
													writer.WriteAttributeString(pdfLayoutSettings.ParagraphAlignment.Key, pdfLayoutSettings.ParagraphAlignment.Value);
												if (pdfLayoutSettings.IsFirstParagraph && !pdfLayoutSettings.CompletedFirstTextNode)
												{
													WriteParagraphAttributes(writer, pdfLayoutSettings.FirstParagraphAttributes);
													if (pdfLayoutSettings.PageBreakBefore)
													{
														writer.WriteAttributeString("startonnewpage", "true");
														pdfLayoutSettings.PageBreakBefore = false;
													}
													if (pdfLayoutSettings.NumberingSchemeType != ChildNumberingSchemeType.None)
													{
														PdfStyle numberingStyle = DetermineNumberingStyle(node, DefaultStyle());
														WriteNumberFragment(writer, pdfLayoutSettings.ParagraphAlignment, pdfLayoutSettings.NumberingSchemeType, pdfLayoutSettings.NumberingIndex, numberingStyle);
													}
												}
												else
												{
													WriteParagraphAttributes(writer, pdfLayoutSettings.OtherParagraphAttributes);
												}
												ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
												pdfLayoutSettings.IsFirstParagraph = false;
											}   // if (node.ChildNodes.Count > 0)
											if (pdfLayoutSettings.OpenParagraphCounter > 0)
											{
												writer.WriteEndElement();  //paragraph
												pdfLayoutSettings.OpenParagraphCounter--;
											}
										}
										break;
									}
								#endregion

								#region case  hr
								case "hr":
									{
										if (pdfLayoutSettings.OpenParagraphCounter > 0)
										{
											writer.WriteEndElement();  //close current paragraph before starting a new one 
											pdfLayoutSettings.OpenParagraphCounter--;
										}

										XmlAttribute attrHrWidth = node.Attributes["size"];
										int lineWidth = 1;
										if (attrHrWidth != null)
											if (!int.TryParse(attrHrWidth.Value, out lineWidth))
												throw new ArgumentException(string.Format("Invalid width parameter on hr tag: '{0}'.", attrHrWidth.Value));
										writer.WriteStartElement("paragraph");
										pdfLayoutSettings.InTextParagraph = false;
										writer.WriteAttributeString("type", "drawing");
										writer.WriteAttributeString("spacingbefore", "3");
										writer.WriteAttributeString("spacingafter", "3");
										writer.WriteAttributeString("width", "540");
										writer.WriteAttributeString("height", lineWidth.ToString());
										writer.WriteStartElement("shape");
										writer.WriteAttributeString("type", "lineshape");
										writer.WriteAttributeString("x", "0");
										writer.WriteAttributeString("y", "0");
										writer.WriteAttributeString("x1", "540");
										writer.WriteAttributeString("y1", "0");
										writer.WriteStartElement("pen");
										writer.WriteAttributeString("color", "black");
										writer.WriteAttributeString("width", lineWidth.ToString());
										writer.WriteEndElement();   // pen
										writer.WriteEndElement();   // shape
										writer.WriteEndElement();   // paragraph
										break;
									}
								#endregion

								#region case  table
								case "table":
									{
										if (pdfLayoutSettings.OpenParagraphCounter > 0)
										{
											writer.WriteEndElement();  //close current paragraph before starting a new one 
											pdfLayoutSettings.OpenParagraphCounter--;
										}
										writer.WriteStartElement("paragraph");
										writer.WriteAttributeString("type", "table");
										writer.WriteAttributeString("spacingbefore", (pdfLayoutSettings.CompletedFirstTextNode ? "0" : PARAGRAPH_SPACING.ToString()));
										pdfLayoutSettings.InTextParagraph = false;
										WriteTableAttributes(writer, node.Attributes, pdfLayoutSettings);
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										pdfLayoutSettings.TableCellSpacing = 0;
										pdfLayoutSettings.TableCellPadding = 0;
										writer.WriteEndElement();   // paragraph
										pdfLayoutSettings.IsFirstParagraph = false;
										break;
									}
								#endregion

								#region case  tr

								case "tr":
									{
										writer.WriteStartElement("row");
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										writer.WriteEndElement();   //  row
										break;
									}
								#endregion

								#region case  td/th
								case "td":
								case "th":
									{
										//save off current pdfLayoutSettings to re-use after the table cell
										PdfLayoutSettings savedPdfLayoutSettings = new PdfLayoutSettings();
										pdfLayoutSettings.CopyTo(ref savedPdfLayoutSettings);
										if (!string.IsNullOrEmpty(pdfLayoutSettings.TableCellAlignment))
										{
											pdfLayoutSettings.FirstParagraphAttributes["horizontalalignment"] = pdfLayoutSettings.TableCellAlignment;
											pdfLayoutSettings.OtherParagraphAttributes["horizontalalignment"] = pdfLayoutSettings.TableCellAlignment;
										}
										//Set selected paragrpah layout attributes
										pdfLayoutSettings.SuppressSpacingBefore = true;
										pdfLayoutSettings.FirstParagraphAttributes = ParagraphAttributes(false, false, 0, false, false, false);
										pdfLayoutSettings.OtherParagraphAttributes = ParagraphAttributes(false, false, 0, false, false, false);

										pdfLayoutSettings.FirstParagraphAttributes = pdfLayoutSettings.OtherParagraphAttributes;

										writer.WriteStartElement("cell");
										WriteCellAttributes(writer, node.Attributes, pdfLayoutSettings);
										if (node.ChildNodes.Count > 0)
										{
											writer.WriteStartElement("paragraph");
											pdfLayoutSettings.InTextParagraph = true;
											pdfLayoutSettings.OpenParagraphCounter++;
											pdfLayoutSettings.ParagraphAlignment = GetParagraphAlignment(node);
											writer.WriteAttributeString("spacingbefore", (pdfLayoutSettings.SuppressSpacingBefore ? "0" : PARAGRAPH_SPACING.ToString()));
											if (!string.IsNullOrEmpty(pdfLayoutSettings.ParagraphAlignment.Key))
												writer.WriteAttributeString(pdfLayoutSettings.ParagraphAlignment.Key, pdfLayoutSettings.ParagraphAlignment.Value);
											if (pdfLayoutSettings.IsFirstParagraph && !pdfLayoutSettings.CompletedFirstTextNode)
											{
												WriteParagraphAttributes(writer, pdfLayoutSettings.FirstParagraphAttributes);
												if (pdfLayoutSettings.PageBreakBefore)
												{
													writer.WriteAttributeString("startonnewpage", "true");
													pdfLayoutSettings.PageBreakBefore = false;
												}
											}
											else
											{
												WriteParagraphAttributes(writer, pdfLayoutSettings.OtherParagraphAttributes);
											}
											ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
											pdfLayoutSettings.IsFirstParagraph = false;
										}   // if (node.ChildNodes.Count > 0)
										if (pdfLayoutSettings.OpenParagraphCounter > 0)
										{
											writer.WriteEndElement();  //paragraph
											pdfLayoutSettings.OpenParagraphCounter--;
										}
										writer.WriteEndElement();   //  cell

										//reset paragrpah layout attributes back to the saved values
										savedPdfLayoutSettings.CopyTo(ref pdfLayoutSettings);
										break;
									}
								#endregion

								#region unused table elements

								case "tbody":
								case "thead":
								case "tfoot":
									{
										ProcessClauseContent(writer, node.ChildNodes, pdfLayoutSettings, styleStack);
										break;
									}
								#endregion

								#region case "img"
								case "img":
									{
										PdfStyle currentStyle = styleStack.Peek();
										writer.WriteStartElement("fragment");
										writer.WriteAttributeString("font", TallPDFFontName(currentStyle.Font));
										writer.WriteAttributeString("fontsize", currentStyle.Font.Size.ToString());
										if (pdfLayoutSettings.SuppressSpaceBetweenFragments)
											if (!char.IsWhiteSpace(node.OuterXml[0]))
												writer.WriteAttributeString("suppressspacebefore", "true");
										if (currentStyle.Font.Underline)
											writer.WriteAttributeString("underline", "true");
										if (currentStyle.Font.Strikeout)
											writer.WriteAttributeString("strikeout", "true");
										if (currentStyle.FontTransform == FontTransform.Subscript)
											writer.WriteAttributeString("subscript", "true");
										else
											if (currentStyle.FontTransform == FontTransform.Superscript)
												writer.WriteAttributeString("superscript", "true");
										writer.WriteString(Utility.XMLHelper.GetText(node));
										writer.WriteEndElement();  //fragment
										break;
									}
								#endregion

								#region "itatImage"
								case XMLNames._A_ITATImageElement:
									{
										//do nothing.  This is processed within the <p> tag, using the ProcessImage() method
										break;
									}
								#endregion

								#region default (throw exception)
								default:
									throw new Exception("XHTML Element not processed:  " + node.OuterXml);
								#endregion
							}
							break;
						}
					#endregion

					#region NodeType == Text
					case XmlNodeType.Text:
						{
							bool createdNewParagraph = false;
							if (pdfLayoutSettings.OpenParagraphCounter <= 0)
							{
								createdNewParagraph = true;
								writer.WriteStartElement("paragraph");  //start new paragraph
								pdfLayoutSettings.InTextParagraph = true;
								pdfLayoutSettings.OpenParagraphCounter++;
								writer.WriteAttributeString("spacingbefore", "0");
								if (!string.IsNullOrEmpty(pdfLayoutSettings.ParagraphAlignment.Key))
									writer.WriteAttributeString(pdfLayoutSettings.ParagraphAlignment.Key, pdfLayoutSettings.ParagraphAlignment.Value);
								if (pdfLayoutSettings.IsFirstParagraph)
								{
									WriteParagraphAttributes(writer, pdfLayoutSettings.FirstParagraphAttributes);
									if (pdfLayoutSettings.PageBreakBefore)
									{
										writer.WriteAttributeString("startonnewpage", "true");
										pdfLayoutSettings.PageBreakBefore = false;
									}
								}
								else
									WriteParagraphAttributes(writer, pdfLayoutSettings.OtherParagraphAttributes);
							}
							PdfStyle currentStyle = styleStack.Peek();
							writer.WriteStartElement("fragment");
							writer.WriteAttributeString("font", TallPDFFontName(currentStyle.Font));
                            if (currentStyle.PreserveWhiteSpace)
							    writer.WriteAttributeString("preservewhitespace", "true");  //RLR,DG v1.5 - added to preserve formatting in text terms (e.g., line breaks)
							writer.WriteAttributeString("fontsize", currentStyle.Font.Size.ToString());
							if (pdfLayoutSettings.SuppressSpaceBetweenFragments)
								if (!char.IsWhiteSpace(node.Value[0]))
									writer.WriteAttributeString("suppressspacebefore", "true");
							if (currentStyle.Font.Underline)
								writer.WriteAttributeString("underline", "true");
							if (currentStyle.Font.Strikeout)
								writer.WriteAttributeString("strikeout", "true");

							if (currentStyle.FontTransform == FontTransform.Subscript)
								writer.WriteAttributeString("subscript", "true");
							else
								if (currentStyle.FontTransform == FontTransform.Superscript)
									writer.WriteAttributeString("superscript", "true");

							writer.WriteString(node.Value);
							writer.WriteEndElement();  //fragment
							//if THIS node does NOT end with a space, then suppress the extra space before the NEXT fragment
							pdfLayoutSettings.SuppressSpaceBetweenFragments = (!node.Value.EndsWith(" "));
							pdfLayoutSettings.CompletedFirstTextNode = true;
							if (createdNewParagraph)
							{
								writer.WriteEndElement();  //paragraph
								pdfLayoutSettings.OpenParagraphCounter--;
							}
							break;
						}
					#endregion

					#region NodeType == Whitespace
					case XmlNodeType.Whitespace:
						{
							bool createdParagraph = false;
							if (pdfLayoutSettings.OpenParagraphCounter <= 0)
							{
								writer.WriteStartElement("paragraph");
								createdParagraph = true;
								pdfLayoutSettings.OpenParagraphCounter++;
								writer.WriteAttributeString("type", "textparagraph");
								writer.WriteAttributeString("spacingbefore", (pdfLayoutSettings.SuppressSpacingBefore ? "0" : PARAGRAPH_SPACING.ToString()));
							}
							PdfStyle currentStyle = styleStack.Peek();
							writer.WriteStartElement("fragment");
							writer.WriteAttributeString("font", TallPDFFontName(currentStyle.Font));
							writer.WriteAttributeString("fontsize", currentStyle.Font.Size.ToString());
							if (pdfLayoutSettings.SuppressSpaceBetweenFragments)
								writer.WriteAttributeString("suppressspacebefore", "true");
							if (currentStyle.Font.Underline)
								writer.WriteAttributeString("underline", "true");
							if (currentStyle.Font.Strikeout)
								writer.WriteAttributeString("strikeout", "true");
							writer.WriteString(node.Value);
							writer.WriteEndElement();  //fragment
							if (createdParagraph)
							{
								writer.WriteEndElement();  // paragraph
								pdfLayoutSettings.OpenParagraphCounter--;
							}
							//DO NOT suppress the space before the NEXT fragment
							pdfLayoutSettings.SuppressSpaceBetweenFragments = false;
							break;
						}
					#endregion

					#region unused NodeTypes (throw exception)
					case XmlNodeType.SignificantWhitespace:
					case XmlNodeType.Attribute:
					case XmlNodeType.CDATA:
					case XmlNodeType.Comment:
					case XmlNodeType.Document:
					case XmlNodeType.DocumentFragment:
					case XmlNodeType.DocumentType:
					case XmlNodeType.EndElement:
					case XmlNodeType.EndEntity:
					case XmlNodeType.Entity:
					case XmlNodeType.EntityReference:
					case XmlNodeType.None:
					case XmlNodeType.Notation:
					case XmlNodeType.ProcessingInstruction:
					case XmlNodeType.XmlDeclaration:
					default:
						throw new Exception(string.Format("XHTML Node not processed:  NodeType={0}, OuterXml=  ", node.NodeType.ToString(), node.OuterXml));
					#endregion
				}
			}
		}