123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using FastReport.Utils;
- namespace FastReport.Export.Pdf
- {
- public partial class PDFExport : ExportBase
- {
- private class PDFOutlineNode
- {
- public string text;
- public int page;
- public float offset;
- public long number;
- public int countTree;
- public int count;
- public PDFOutlineNode first;
- public PDFOutlineNode last;
- public PDFOutlineNode parent;
- public PDFOutlineNode prev;
- public PDFOutlineNode next;
- public PDFOutlineNode()
- {
- text = String.Empty;
- offset = -1;
- number = 0;
- count = 0;
- countTree = 0;
- }
- }
- private PDFOutlineNode outlineTree;
- private long BuildOutline(PDFOutlineNode node, XmlItem xml)
- {
- PDFOutlineNode prev = null;
- PDFOutlineNode current = null;
- long currNumber = node.number;
- for (int i = 0; i < xml.Count; i++)
- {
- int page = 0;
- float offset = 0f;
- string s = xml[i].GetProp("Page");
- if (s != "")
- {
- page = int.Parse(s);
- s = xml[i].GetProp("Offset");
- if (s != "")
- offset = (float)Converter.FromString(typeof(float), s) * PDF_DIVIDER;
- }
- // add check of page range
- current = new PDFOutlineNode();
- current.text = xml[i].GetProp("Text");
- current.page = page;
- current.offset = offset;
- current.prev = prev;
- if (prev != null)
- prev.next = current;
- else
- node.first = current;
- prev = current;
- current.parent = node;
- current.number = currNumber + 1;
- currNumber = BuildOutline(current, xml[i]);
- node.count++;
- node.countTree += current.countTree + 1;
- }
- node.last = current;
- return currNumber;
- }
- private void WriteOutline(PDFOutlineNode item)
- {
- long number;
- if (item.parent != null)
- number = UpdateXRef();
- else
- number = item.number;
- StringBuilder sb = new StringBuilder();
- sb.AppendLine(ObjNumber(number));
- sb.AppendLine("<<");
- if (item.text != String.Empty)
- {
- sb.Append("/Title ");
- PrepareString(item.text, encKey, encrypted, number, sb);
- sb.AppendLine();
- }
- if (item.parent != null)
- sb.Append("/Parent ").AppendLine(ObjNumberRef(item.parent.number));
- if (item.count > 0)
- sb.Append("/Count ").AppendLine(item.count.ToString());
- if (item.first != null)
- sb.Append("/First ").AppendLine(ObjNumberRef(item.first.number));
- if (item.last != null)
- sb.Append("/Last ").AppendLine(ObjNumberRef(item.last.number));
- if (item.prev != null)
- sb.Append("/Prev ").AppendLine(ObjNumberRef(item.prev.number));
- if (item.next != null)
- sb.Append("/Next ").AppendLine(ObjNumberRef(item.next.number));
- if (item.page < pagesRef.Count)
- {
- sb.Append("/Dest [");
- sb.Append(ObjNumberRef(pagesRef[item.page]));
- sb.Append(" /XYZ 0 ");
- sb.Append(Math.Round(pagesHeights[item.page] - item.offset).ToString());
- sb.Append(" 0]");
- }
- sb.AppendLine(">>");
- sb.AppendLine("endobj");
- WriteLn(pdf, sb.ToString());
- if (item.first != null)
- WriteOutline(item.first);
- if (item.next != null)
- WriteOutline(item.next);
- }
- }
- }
|