public void Add(BlockNode block) { _blocks.Add(block); }
public override void Render(Surface surface, float left, float width) { // // Determine the maximum number of Columns in the rows in this table // int maxColumns = 0; foreach (TableRowNode row in childNodes) { int columns = row.MinMaxWidths(surface, width).Count; if (maxColumns < columns) { maxColumns = columns; } } // // Initialise an Array of MinMax's for the maximum number of Columns // MinMax[] colWidths = new MinMax[maxColumns]; for (int i = 0; i < maxColumns; i++) { colWidths[i] = new MinMax(0, 0); } // // Now, for each column, determine the biggest MinWidth and biggest MaxWidth in all rows // foreach (TableRowNode row in childNodes) { List <MinMax> blockWidths = row.MinMaxWidths(surface, width); for (int i = 0; i < blockWidths.Count; i++) { if (colWidths[i].MinWidth < blockWidths[i].MinWidth) { colWidths[i].MinWidth = blockWidths[i].MinWidth; } if (colWidths[i].MaxWidth < blockWidths[i].MaxWidth) { colWidths[i].MaxWidth = blockWidths[i].MaxWidth; } } } // // Determine what the ratios are between all colWidths[n].MaxWidth // float totalMaxWidth = 0; for (int i = 0; i < maxColumns; i++) { totalMaxWidth += colWidths[i].MaxWidth; } float[] widthRatio = new float[maxColumns]; for (int i = 0; i < maxColumns; i++) { widthRatio[i] = colWidths[i].MaxWidth / totalMaxWidth; } // // Determine optimum column widths // float gutterWidth = width * 0.03f; // make each gutter 3% of total available width float totalGutters = gutterWidth * (maxColumns - 1); for (int i = 0; i < maxColumns; i++) { colWidths[i].MaxWidth = widthRatio[i] * (width - totalGutters); } foreach (TableRowNode row in childNodes) { float savedCurrentY = surface.CurrentY; float maxCurrentY = float.MinValue; int i = 0; float x = left; foreach (Node node in row) { BlockNode block = (BlockNode)node; surface.CurrentY = savedCurrentY; block.Render(surface, x, colWidths[i].MaxWidth); x += colWidths[i++].MaxWidth + gutterWidth; if (maxCurrentY < surface.CurrentY) { maxCurrentY = surface.CurrentY; } } surface.CurrentY = maxCurrentY; } }
private void Lax_StartElement(string elementName, Dictionary <string, string> attributes) { try { elementName = elementName.ToLower(); string id = null; if (attributes.ContainsKey("id")) { id = attributes["id"]; } switch (elementName) { case "b": // bold case "i": // italic case "u": // underline case "em": // italic case "strong": // bold case "small": // smaller font case "big": // larger font case "code": // non-proportional case "tt": // non-proportional (teletype) AssertState(elementName, NodeType.Block); currentNode.AddChild(Node.TextFormatNode(elementName)); break; default: { switch (elementName) { case "div": // We ignore all <div> unless class="cut", meaning cut the paper if (attributes.ContainsKey("class") && attributes["class"].ToLower() == "cut") { AssertState(elementName, NodeType.Document); currentNode.AddChild(new HorizontalRuleNode(id, true)); } break; case "p": case "h1": case "h2": case "h3": case "h4": case "h5": case "li": case "td": // Table Data case "th": // Header AssertState(elementName, new[] { NodeType.Document, NodeType.TableRow, NodeType.Block }); var block = new BlockNode(elementName, id); currentNode = currentNode.AddChild(block); if (HeaderTags.Contains(elementName)) { // Header elementName implies its own formatting block.AddChild(Node.TextFormatNode(elementName)); block.Alignment = StringAlignment.Center; } // // Process attributes // if (attributes.ContainsKey("align")) { if (attributes["align"] == "left") { block.Alignment = StringAlignment.Near; } else if (attributes["align"] == "center" || attributes["align"] == "centre") { block.Alignment = StringAlignment.Center; } else if (attributes["align"] == "right") { block.Alignment = StringAlignment.Far; } } if (attributes.ContainsKey("valign")) { if (attributes["valign"] == "top") { block.VerticalAlignment = StringAlignment.Near; } else if (attributes["valign"] == "middle") { block.VerticalAlignment = StringAlignment.Center; } else if (attributes["align"] == "bottom") { block.VerticalAlignment = StringAlignment.Far; } } if (attributes.ContainsKey("class")) { if (attributes["class"] == "barcode") { block.HangingIndent = 0; // do nothing } else if (attributes["class"] == "hanging-indent") { block.HangingIndent = 4; } else if (attributes["class"] == "hanging-indent-large") { block.HangingIndent = 12; } } if (elementName == "li") { Debug.Assert(listIndex != 0); block.ListItemIndex = listIndex; if (listIndex > 0) { listIndex++; } } break; case "dt": // Definition Term case "dd": // Definition List AssertState(elementName, new NodeType[] { NodeType.Document, NodeType.Table, NodeType.TableRow }); // In case there was no <dl> element, make sure we are inside a TableRowNode... if (currentNode.Type == NodeType.Document) { currentNode = currentNode.AddChild(new TableNode(id)); impliedTags.Push(new ImpliedTag("dd", "table")); } if (currentNode.Type == NodeType.Table) { currentNode = currentNode.AddChild(new TableRowNode(id)); } currentNode = currentNode.AddChild(new BlockNode(elementName, id)); break; case "ul": // Unordered List listIndex = -1; break; case "ol": // Ordered List listIndex = 1; break; case "dl": case "table": AssertState(elementName, new[] { NodeType.Document, NodeType.Block }); currentNode = currentNode.AddChild(new TableNode(id)); break; case "tr": // Table Row AssertState(elementName, new[] { NodeType.Document, NodeType.Table }); if (currentNode.Type == NodeType.Document) { currentNode = currentNode.AddChild(new TableNode(id)); } currentNode = currentNode.AddChild(new TableRowNode(id)); break; case "img": AssertState(elementName, new[] { NodeType.Document, NodeType.Block }); if (currentNode.Type == NodeType.Document) { block = new BlockNode(elementName, id); block.Alignment = StringAlignment.Center; currentNode = currentNode.AddChild(block); impliedTags.Push(new ImpliedTag(elementName, "p")); } if (attributes.ContainsKey("class") && (attributes["class"] == "barcode")) { BarcodeNode barcodeNode = new BarcodeNode(id); if (attributes.ContainsKey("src")) { barcodeNode.Source = (attributes["src"]); } currentNode.AddChild(barcodeNode); } else // NOT a barcode { ImageNode imageNode = new ImageNode(id); if (attributes.ContainsKey("src")) { imageNode.Source = (attributes["src"]); } currentNode.AddChild(imageNode); } break; case "hr": AssertState(elementName, NodeType.Document); currentNode.AddChild(new HorizontalRuleNode(id, false)); break; default: // Debug.Assert(false); break; } } break; } } catch (Exception) { throw; } }