NumberedList2.vb
  1. ''
  2. '' This code is part of Document Solutions for PDF demos.
  3. '' Copyright (c) MESCIUS inc. All rights reserved.
  4. ''
  5. Imports System.IO
  6. Imports System.Drawing
  7. Imports System.Text
  8. Imports GrapeCity.Documents.Pdf
  9. Imports GrapeCity.Documents.Text
  10. Imports GrapeCity.Documents.Drawing
  11.  
  12. '' Demonstrates how different styles of numbered lists can be rendered in DsPdf.
  13. '' See also NumberedList.
  14. Public Class NumberedList2
  15. '' Encapsulate page layout constants used in the sample:
  16. Private Structure Layout
  17. '' All around page margins:
  18. Public Shared Margin As Single = 72.0F
  19. '' List offset relative to item number:
  20. Public Shared ListOffset As Single = 24.0F
  21. '' List level indent:
  22. Public Shared ListIndent As Single = 30.0F
  23. End Structure
  24.  
  25. '' Define simple tree type:
  26. Private Class Node
  27. Public Sub New(ByVal txt As String)
  28. Text = txt
  29. End Sub
  30. Public Property Text As String
  31. Public Property Children As List(Of Node) = New List(Of Node)()
  32. End Class
  33.  
  34. '' Renders a list of nodes as a numbered list.
  35. Private Function RenderNodes(ByRef page As Page, ByVal pt As PointF, ByVal nodes As List(Of Node), ByVal level As Integer) As PointF
  36.  
  37. Dim tlBullet = page.Graphics.CreateTextLayout()
  38. tlBullet.DefaultFormat.Font = StandardFonts.Times
  39. tlBullet.MarginLeft = Layout.ListIndent * level
  40.  
  41. Dim tlText = New TextLayout(72)
  42. tlText.DefaultFormat.Font = StandardFonts.Times
  43. tlText.MarginLeft = Layout.ListOffset + Layout.ListIndent * level
  44.  
  45. For i = 0 To nodes.Count - 1
  46. Dim g = page.Graphics
  47. '' Prep item text:
  48. tlText.Clear()
  49. tlText.Append(nodes(i).Text)
  50. tlText.PerformLayout(True)
  51. If pt.Y + tlText.ContentHeight > page.Size.Height - Layout.Margin Then
  52. page = page.Doc.NewPage()
  53. g = page.Graphics
  54. pt.Y = Layout.Margin
  55. End If
  56. '' Prep item number:
  57. tlBullet.Clear()
  58. tlBullet.Append(ItemIdxToString(i, level, tlBullet))
  59. tlBullet.PerformLayout(True)
  60. '' Render item:
  61. g.DrawTextLayout(tlBullet, pt)
  62. g.DrawTextLayout(tlText, pt)
  63. '' Advance insertion point:
  64. pt.Y += tlText.ContentHeight
  65. '' Render children:
  66. If nodes(i).Children.Count > 0 Then
  67. pt = RenderNodes(page, pt, nodes(i).Children, level + 1)
  68. End If
  69. Next
  70. Return pt
  71. End Function
  72.  
  73. '' Convert item index to item number representation, in a
  74. '' Arabic -> Latin letters -> Roman numbers loop.
  75. '' Roman numbers are right-aligned, others are left-aligned.
  76. Private Function ItemIdxToString(ByVal itemIdx As Integer, ByVal level As Integer, ByVal tl As TextLayout) As String
  77.  
  78. Select Case (level Mod 3)
  79. Case 0
  80. tl.MarginLeft = Layout.ListIndent * level
  81. tl.MaxWidth = Nothing
  82. tl.TextAlignment = TextAlignment.Leading
  83. Return $"{itemIdx + 1}."
  84. Case 1
  85. tl.MarginLeft = Layout.ListIndent * level
  86. tl.MaxWidth = Nothing
  87. tl.TextAlignment = TextAlignment.Leading
  88. Return $"{ChrW(AscW("a") + itemIdx)}."
  89. Case 2
  90. tl.MarginLeft = 0
  91. Dim font = tl.DefaultFormat.Font
  92. tl.MaxWidth = Layout.ListIndent * level + tl.DefaultFormat.FontSize
  93. tl.TextAlignment = TextAlignment.Trailing
  94. Return $"{IntToRoman(itemIdx + 1)}."
  95. Case Else
  96. Throw New Exception("Unexpected.")
  97. End Select
  98. End Function
  99.  
  100. '' From http://dotnet-snippets.com/snippet/roman-numerals/667
  101. Private Function IntToRoman(ByVal number As Integer) As String
  102.  
  103. Dim result = New StringBuilder()
  104. Dim digitsValues = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000}
  105. Dim romanDigits = {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"}
  106. While number > 0
  107. For i = digitsValues.Count() - 1 To 0 Step -1
  108. If (number / digitsValues(i) >= 1) Then
  109. number -= digitsValues(i)
  110. result.Append(romanDigits(i).ToLower())
  111. Exit For
  112. End If
  113. Next
  114. End While
  115. Return result.ToString()
  116. End Function
  117.  
  118. '' Main entry point:
  119. Function CreatePDF(ByVal stream As Stream) As Integer
  120. Dim doc = New GcPdfDocument()
  121. Dim page = doc.NewPage()
  122. RenderNodes(page, New PointF(Layout.Margin, Layout.Margin), _arthrapods.Children, 0)
  123. ''
  124. '' Done:
  125. doc.Save(stream)
  126. Return doc.Pages.Count
  127. End Function
  128.  
  129. '' Sample tree data:
  130. Private _arthrapods As New Node("Animalia Arthrapoda") With
  131. {
  132. .Children = New List(Of Node) From
  133. {
  134. New Node("Insecta") With
  135. {
  136. .Children = New List(Of Node) From
  137. {
  138. New Node("Archaeognatha") With
  139. {
  140. .Children = New List(Of Node) From
  141. {
  142. New Node("Protozoa")
  143. }
  144. },
  145. New Node("Thysanura") With
  146. {
  147. .Children = New List(Of Node) From
  148. {
  149. New Node("Silverfish")
  150. }
  151. },
  152. New Node("Ephemeoptera") With
  153. {
  154. .Children = New List(Of Node) From
  155. {
  156. New Node("Mafly")
  157. }
  158. },
  159. New Node("Odonata") With
  160. {
  161. .Children = New List(Of Node) From
  162. {
  163. New Node("Dragonfly"),
  164. New Node("Azure Damzelfly"),
  165. New Node("Emerald Damzelfly")
  166. }
  167. },
  168. New Node("Orthoptera") With
  169. {
  170. .Children = New List(Of Node) From
  171. {
  172. New Node("Grasshopper"),
  173. New Node("Cricket"),
  174. New Node("Cave Cricket")
  175. }
  176. },
  177. New Node("Phasmatodea") With
  178. {
  179. .Children = New List(Of Node) From
  180. {
  181. New Node("Walking Stick"),
  182. New Node("Leaf Bug")
  183. }
  184. },
  185. New Node("Mantodea") With
  186. {
  187. .Children = New List(Of Node) From
  188. {
  189. New Node("Praying Mantis")
  190. }
  191. },
  192. New Node("Blattoeda") With
  193. {
  194. .Children = New List(Of Node) From
  195. {
  196. New Node("Cockroach")
  197. }
  198. },
  199. New Node("Isoptera") With
  200. {
  201. .Children = New List(Of Node) From
  202. {
  203. New Node("Termite")
  204. }
  205. },
  206. New Node("Phithiraptera") With
  207. {
  208. .Children = New List(Of Node) From
  209. {
  210. New Node("Bird Lice"),
  211. New Node("Human Lice"),
  212. New Node("Pubic Lice")
  213. }
  214. },
  215. New Node("Hemiptera") With
  216. {
  217. .Children = New List(Of Node) From
  218. {
  219. New Node("Cicada"),
  220. New Node("Pond Skater"),
  221. New Node("Tree Hopper"),
  222. New Node("Stink Bug"),
  223. New Node("Thrip"),
  224. New Node("Alderfly")
  225. }
  226. },
  227. New Node("Siphonatera") With
  228. {
  229. .Children = New List(Of Node) From
  230. {
  231. New Node("Flea")
  232. }
  233. }
  234. }
  235. },
  236. New Node("Myriapoda") With
  237. {
  238. .Children = New List(Of Node) From
  239. {
  240. New Node("Chilopoda") With
  241. {
  242. .Children = New List(Of Node) From
  243. {
  244. New Node("Centipede")
  245. }
  246. },
  247. New Node("Diplopoda") With
  248. {
  249. .Children = New List(Of Node) From
  250. {
  251. New Node("Millipede"),
  252. New Node("Pitbug")
  253. }
  254. }
  255. }
  256. },
  257. New Node("Crustacea") With
  258. {
  259. .Children = New List(Of Node) From
  260. {
  261. New Node("Branchiopod") With
  262. {
  263. .Children = New List(Of Node) From
  264. {
  265. New Node("Brine Shrimp"),
  266. New Node("Water Flea")
  267. }
  268. },
  269. New Node("Maxillopod") With
  270. {
  271. .Children = New List(Of Node) From
  272. {
  273. New Node("Cyclopoid"),
  274. New Node("Calgid"),
  275. New Node("Barnacles")
  276. }
  277. },
  278. New Node("Malacostracan") With
  279. {
  280. .Children = New List(Of Node) From
  281. {
  282. New Node("Krill"),
  283. New Node("Prawn"),
  284. New Node("Shrimp"),
  285. New Node("Cancrid Crab"),
  286. New Node("Fidder Crab"),
  287. New Node("Spider Crab"),
  288. New Node("Lobster"),
  289. New Node("Hermit Crab"),
  290. New Node("Cray Fish")
  291. }
  292. }
  293. }
  294. },
  295. New Node("Pycnogonida") With
  296. {
  297. .Children = New List(Of Node) From
  298. {
  299. New Node("Pycnogonida") With
  300. {
  301. .Children = New List(Of Node) From
  302. {
  303. New Node("Sea Spider")
  304. }
  305. }
  306. }
  307. },
  308. New Node("Merostomata") With
  309. {
  310. .Children = New List(Of Node) From
  311. {
  312. New Node("Merostomata") With
  313. {
  314. .Children = New List(Of Node) From
  315. {
  316. New Node("Horseshoe Spider")
  317. }
  318. }
  319. }
  320. },
  321. New Node("Arachnida") With
  322. {
  323. .Children = New List(Of Node) From
  324. {
  325. New Node("Scorpiones") With
  326. {
  327. .Children = New List(Of Node) From
  328. {
  329. New Node("Buthid"),
  330. New Node("Imperial Scorpion")
  331. }
  332. },
  333. New Node("Pseudoscorpions") With
  334. {
  335. .Children = New List(Of Node) From
  336. {
  337. New Node("Neobisiid"),
  338. New Node("Cheliferid")
  339. }
  340. },
  341. New Node("Solfigugae") With
  342. {
  343. .Children = New List(Of Node) From
  344. {
  345. New Node("Wind Scorpion")
  346. }
  347. },
  348. New Node("Acari") With
  349. {
  350. .Children = New List(Of Node) From
  351. {
  352. New Node("Tick"),
  353. New Node("Mite")
  354. }
  355. },
  356. New Node("Araneae") With
  357. {
  358. .Children = New List(Of Node) From
  359. {
  360. New Node("Crib Weaver"),
  361. New Node("Funnel-web Spider"),
  362. New Node("Funnel Weaver"),
  363. New Node("Water Spider"),
  364. New Node("Jumping Spider"),
  365. New Node("Wolf Spider"),
  366. New Node("Nursery-web Spider"),
  367. New Node("Crab Spider"),
  368. New Node("Black Widow"),
  369. New Node("Tiger Oriental Tarantula"),
  370. New Node("Mexican Red-legged Tarantula")
  371. }
  372. }
  373. }
  374. }
  375. }
  376. }
  377. End Class
  378.