NumberedList2.cs
- //
- // This code is part of Document Solutions for PDF demos.
- // Copyright (c) MESCIUS inc. All rights reserved.
- //
- using System;
- using System.IO;
- using System.Drawing;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using GrapeCity.Documents.Pdf;
- using GrapeCity.Documents.Text;
- using GrapeCity.Documents.Drawing;
-
- namespace DsPdfWeb.Demos.Basics
- {
- // This sample demonstrates how different styles of numbered lists
- // can be rendered in DsPdf.
- // See also NumberedList.
- public class NumberedList2
- {
- // Encapsulate page layout constants used in the sample:
- private struct Layout
- {
- // All around page margins:
- public static float Margin => 72;
- // List offset relative to item number:
- public static float ListOffset => 24;
- // List level indent:
- public static float ListIndent => 30;
- };
-
- // Define simple tree type:
- private class Node
- {
- public Node(string text)
- {
- Text = text;
- }
- public string Text { get; }
- public List<Node> Children = new List<Node>();
- }
-
- // Renders a list of nodes as a numbered list.
- private PointF RenderNodes(ref Page page, PointF pt, List<Node> nodes, int level)
- {
- var tlBullet = new TextLayout(72);
- tlBullet.DefaultFormat.Font = StandardFonts.Times;
- tlBullet.MarginLeft = Layout.ListIndent * level;
-
- var tlText = new TextLayout(72);
- tlText.DefaultFormat.Font = StandardFonts.Times;
- tlText.MarginLeft = Layout.ListOffset + Layout.ListIndent * level;
-
- for (int i = 0; i < nodes.Count; ++i)
- {
- var g = page.Graphics;
- // Prep item text:
- tlText.Clear();
- tlText.Append(nodes[i].Text);
- tlText.PerformLayout(true);
- if (pt.Y + tlText.ContentHeight > page.Size.Height - Layout.Margin)
- {
- page = page.Doc.NewPage();
- g = page.Graphics;
- pt.Y = Layout.Margin;
- }
- // Prep item number:
- tlBullet.Clear();
- tlBullet.Append(ItemIdxToString(i, level, tlBullet));
- tlBullet.PerformLayout(true);
- // Render item:
- g.DrawTextLayout(tlBullet, pt);
- g.DrawTextLayout(tlText, pt);
- // Advance insertion point:
- pt.Y += tlText.ContentHeight;
- // Render children:
- if (nodes[i].Children.Count > 0)
- pt = RenderNodes(ref page, pt, nodes[i].Children, level + 1);
- }
- return pt;
- }
-
- // Convert item index to item number representation, in a
- // Arabic -> Latin letters -> Roman numbers loop.
- // Roman numbers are right-aligned, others are left-aligned.
- private string ItemIdxToString(int itemIdx, int level, TextLayout tl)
- {
- switch (level % 3)
- {
- case 0:
- tl.MarginLeft = Layout.ListIndent * level;
- tl.MaxWidth = null;
- tl.TextAlignment = TextAlignment.Leading;
- return $"{itemIdx + 1}.";
- case 1:
- tl.MarginLeft = Layout.ListIndent * level;
- tl.MaxWidth = null;
- tl.TextAlignment = TextAlignment.Leading;
- return $"{(char)('a' + itemIdx)}.";
- case 2:
- tl.MarginLeft = 0;
- var font = tl.DefaultFormat.Font;
- tl.MaxWidth = Layout.ListIndent * level + tl.DefaultFormat.FontSize;
- tl.TextAlignment = TextAlignment.Trailing;
- return $"{IntToRoman(itemIdx + 1)}.";
- default:
- throw new Exception("Unexpected.");
- }
- }
-
- // From http://dotnet-snippets.com/snippet/roman-numerals/667
- private string IntToRoman(int number)
- {
- var result = new StringBuilder();
- int[] digitsValues = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
- string[] romanDigits = { "I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M" };
- while (number > 0)
- {
- for (int i = digitsValues.Count() - 1; i >= 0; i--)
- if (number / digitsValues[i] >= 1)
- {
- number -= digitsValues[i];
- result.Append(romanDigits[i].ToLower());
- break;
- }
- }
- return result.ToString();
- }
-
- // Main entry point:
- public int CreatePDF(Stream stream)
- {
- var doc = new GcPdfDocument();
- var page = doc.NewPage();
- RenderNodes(ref page, new PointF(Layout.Margin, Layout.Margin), _arthrapods.Children, 0);
- // Done:
- doc.Save(stream);
- return doc.Pages.Count;
- }
-
- // Sample tree data:
- private Node _arthrapods = new Node("Animalia Arthrapoda")
- {
- Children = new List<Node>()
- {
- new Node("Insecta")
- {
- Children = new List<Node>()
- {
- new Node("Archaeognatha")
- {
- Children = new List<Node>()
- {
- new Node("Protozoa")
- },
- },
- new Node("Thysanura")
- {
- Children = new List<Node>()
- {
- new Node("Silverfish")
- },
- },
- new Node("Ephemeoptera")
- {
- Children = new List<Node>()
- {
- new Node("Mafly")
- },
- },
- new Node("Odonata")
- {
- Children = new List<Node>()
- {
- new Node("Dragonfly"),
- new Node("Azure Damzelfly"),
- new Node("Emerald Damzelfly"),
- },
- },
- new Node("Orthoptera")
- {
- Children = new List<Node>()
- {
- new Node("Grasshopper"),
- new Node("Cricket"),
- new Node("Cave Cricket"),
- },
- },
- new Node("Phasmatodea")
- {
- Children = new List<Node>()
- {
- new Node("Walking Stick"),
- new Node("Leaf Bug"),
- },
- },
- new Node("Mantodea")
- {
- Children = new List<Node>()
- {
- new Node("Praying Mantis"),
- },
- },
- new Node("Blattoeda")
- {
- Children = new List<Node>()
- {
- new Node("Cockroach"),
- },
- },
- new Node("Isoptera")
- {
- Children = new List<Node>()
- {
- new Node("Termite"),
- },
- },
- new Node("Phithiraptera")
- {
- Children = new List<Node>()
- {
- new Node("Bird Lice"),
- new Node("Human Lice"),
- new Node("Pubic Lice"),
- },
- },
- new Node("Hemiptera")
- {
- Children = new List<Node>()
- {
- new Node("Cicada"),
- new Node("Pond Skater"),
- new Node("Tree Hopper"),
- new Node("Stink Bug"),
- new Node("Thrip"),
- new Node("Alderfly"),
- },
- },
- new Node("Siphonatera")
- {
- Children = new List<Node>()
- {
- new Node("Flea"),
- },
- },
- // Coleoptera etc skipped
- },
- },
- new Node("Myriapoda")
- {
- Children = new List<Node>()
- {
- new Node("Chilopoda")
- {
- Children = new List<Node>()
- {
- new Node("Centipede"),
- },
- },
- new Node("Diplopoda")
- {
- Children = new List<Node>()
- {
- new Node("Millipede"),
- new Node("Pitbug"),
- },
- },
- },
- },
- new Node("Crustacea")
- {
- Children = new List<Node>()
- {
- new Node("Branchiopod")
- {
- Children = new List<Node>()
- {
- new Node("Brine Shrimp"),
- new Node("Water Flea"),
- },
- },
- new Node("Maxillopod")
- {
- Children = new List<Node>()
- {
- new Node("Cyclopoid"),
- new Node("Calgid"),
- new Node("Barnacles"),
- },
- },
- new Node("Malacostracan")
- {
- Children = new List<Node>()
- {
- new Node("Krill"),
- new Node("Prawn"),
- new Node("Shrimp"),
- new Node("Cancrid Crab"),
- new Node("Fidder Crab"),
- new Node("Spider Crab"),
- new Node("Lobster"),
- new Node("Hermit Crab"),
- new Node("Cray Fish"),
- },
- },
- },
- },
- new Node("Pycnogonida")
- {
- Children = new List<Node>()
- {
- new Node("Pycnogonida")
- {
- Children = new List<Node>()
- {
- new Node("Sea Spider"),
- },
- },
- },
- },
- new Node("Merostomata")
- {
- Children = new List<Node>()
- {
- new Node("Merostomata")
- {
- Children = new List<Node>()
- {
- new Node("Horseshoe Spider"),
- },
- },
- },
- },
- new Node("Arachnida")
- {
- Children = new List<Node>()
- {
- new Node("Scorpiones")
- {
- Children = new List<Node>()
- {
- new Node("Buthid"),
- new Node("Imperial Scorpion"),
- },
- },
- new Node("Pseudoscorpions")
- {
- Children = new List<Node>()
- {
- new Node("Neobisiid"),
- new Node("Cheliferid"),
- },
- },
- new Node("Solfigugae")
- {
- Children = new List<Node>()
- {
- new Node("Wind Scorpion"),
- },
- },
- new Node("Acari")
- {
- Children = new List<Node>()
- {
- new Node("Tick"),
- new Node("Mite"),
- },
- },
- new Node("Araneae")
- {
- Children = new List<Node>()
- {
- new Node("Crib Weaver"),
- new Node("Funnel-web Spider"),
- new Node("Funnel Weaver"),
- new Node("Water Spider"),
- new Node("Jumping Spider"),
- new Node("Wolf Spider"),
- new Node("Nursery-web Spider"),
- new Node("Crab Spider"),
- new Node("Black Widow"),
- new Node("Tiger Oriental Tarantula"),
- new Node("Mexican Red-legged Tarantula"),
- },
- },
- },
- },
- },
- };
- }
- }
-