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