protected void FillOCProperties(bool erase) { if (vOCProperties == null) vOCProperties = new PdfOCProperties(); if (erase) { vOCProperties.Remove(PdfName.OCGS); vOCProperties.Remove(PdfName.D); } if (vOCProperties.Get(PdfName.OCGS) == null) { PdfArray gr = new PdfArray(); foreach (PdfLayer layer in documentOCG.Keys) { gr.Add(layer.Ref); } vOCProperties.Put(PdfName.OCGS, gr); } if (vOCProperties.Get(PdfName.D) != null) return; List<IPdfOCG> docOrder = new List<IPdfOCG>(documentOCGorder); for (ListIterator<IPdfOCG> it = new ListIterator<IPdfOCG>(docOrder); it.HasNext();) { PdfLayer layer = (PdfLayer)it.Next(); if (layer.Parent != null) it.Remove(); } PdfArray order = new PdfArray(); foreach (PdfLayer layer in docOrder) { GetOCGOrder(order, layer); } PdfDictionary d = new PdfDictionary(); vOCProperties.Put(PdfName.D, d); d.Put(PdfName.ORDER, order); PdfArray grx = new PdfArray(); foreach (PdfLayer layer in documentOCG.Keys) { if (!layer.On) grx.Add(layer.Ref); } if (grx.Size > 0) d.Put(PdfName.OFF, grx); if (OCGRadioGroup.Size > 0) d.Put(PdfName.RBGROUPS, OCGRadioGroup); if (OCGLocked.Size > 0) d.Put(PdfName.LOCKED, OCGLocked); AddASEvent(PdfName.VIEW, PdfName.ZOOM); AddASEvent(PdfName.VIEW, PdfName.VIEW); AddASEvent(PdfName.PRINT, PdfName.PRINT); AddASEvent(PdfName.EXPORT, PdfName.EXPORT); d.Put(PdfName.LISTMODE, PdfName.VISIBLEPAGES); }
/** * Generates a list of numbers from a string. * @param ranges the comma separated ranges * @param maxNumber the maximum number in the range * @return a list with the numbers as <CODE>Integer</CODE> */ public static ICollection<int> Expand(String ranges, int maxNumber) { SequenceList parse = new SequenceList(ranges); List<int> list = new List<int>(); bool sair = false; while (!sair) { sair = parse.GetAttributes(); if (parse.low == -1 && parse.high == -1 && !parse.even && !parse.odd) continue; if (parse.low < 1) parse.low = 1; if (parse.high < 1 || parse.high > maxNumber) parse.high = maxNumber; if (parse.low > maxNumber) parse.low = maxNumber; //System.out.Println("low="+parse.low+",high="+parse.high+",odd="+parse.odd+",even="+parse.even+",inverse="+parse.inverse); int inc = 1; if (parse.inverse) { if (parse.low > parse.high) { int t = parse.low; parse.low = parse.high; parse.high = t; } for (ListIterator<int> it = new ListIterator<int>(list); it.HasNext();) { int n = it.Next(); if (parse.even && (n & 1) == 1) continue; if (parse.odd && (n & 1) == 0) continue; if (n >= parse.low && n <= parse.high) it.Remove(); } } else { if (parse.low > parse.high) { inc = -1; if (parse.odd || parse.even) { --inc; if (parse.even) parse.low &= ~1; else parse.low -= ((parse.low & 1) == 1 ? 0 : 1); } for (int k = parse.low; k >= parse.high; k += inc) { list.Add(k); } } else { if (parse.odd || parse.even) { ++inc; if (parse.odd) parse.low |= 1; else parse.low += ((parse.low & 1) == 1 ? 1 : 0); } for (int k = parse.low; k <= parse.high; k += inc) list.Add(k); } } } return list; }
/** * Removes the bookmark entries for a number of page ranges. The page ranges * consists of a number of pairs with the start/end page range. The page numbers * are inclusive. * @param list the bookmarks * @param pageRange the page ranges, always in pairs. */ public static void EliminatePages(ArrayList list, int[] pageRange) { if (list == null) return; for (ListIterator it = new ListIterator(list); it.HasNext();) { Hashtable map = (Hashtable)it.Next(); bool hit = false; if ("GoTo".Equals(map["Action"])) { String page = (String)map["Page"]; if (page != null) { page = page.Trim(); int idx = page.IndexOf(' '); int pageNum; if (idx < 0) pageNum = int.Parse(page); else pageNum = int.Parse(page.Substring(0, idx)); int len = pageRange.Length & 0x7ffffffe; for (int k = 0; k < len; k += 2) { if (pageNum >= pageRange[k] && pageNum <= pageRange[k + 1]) { hit = true; break; } } } } ArrayList kids = (ArrayList)map["Kids"]; if (kids != null) { EliminatePages(kids, pageRange); if (kids.Count == 0) { map.Remove("Kids"); kids = null; } } if (hit) { if (kids == null) it.Remove(); else { map.Remove("Action"); map.Remove("Page"); map.Remove("Named"); } } } }
/** * Removes the bookmark entries for a number of page ranges. The page ranges * consists of a number of pairs with the start/end page range. The page numbers * are inclusive. * @param list the bookmarks * @param pageRange the page ranges, always in pairs. */ public static void EliminatePages(IList<Dictionary<String, Object>> list, int[] pageRange) { if (list == null) return; for (ListIterator<Dictionary<String, Object>> it = new ListIterator<Dictionary<string,object>>(list); it.HasNext();) { Dictionary<String, Object> map = it.Next(); bool hit = false; if (map.ContainsKey("Action") && "GoTo".Equals(map["Action"])) { String page = null; if (map.ContainsKey("Page")) page = (String)map["Page"]; if (page != null) { page = page.Trim(); int idx = page.IndexOf(' '); int pageNum; if (idx < 0) pageNum = int.Parse(page); else pageNum = int.Parse(page.Substring(0, idx)); int len = pageRange.Length & 0x7ffffffe; for (int k = 0; k < len; k += 2) { if (pageNum >= pageRange[k] && pageNum <= pageRange[k + 1]) { hit = true; break; } } } } IList<Dictionary<String, Object>> kids = null; if (map.ContainsKey("Kids")) kids = (IList<Dictionary<String, Object>>)map["Kids"]; if (kids != null) { EliminatePages(kids, pageRange); if (kids.Count == 0) { map.Remove("Kids"); kids = null; } } if (hit) { if (kids == null) it.Remove(); else { map.Remove("Action"); map.Remove("Page"); map.Remove("Named"); } } } }
/** * Adds a new table to * @param table Table to add. Rendered rows will be deleted after processing. * @param onlyFirstPage Render only the first full page * @throws DocumentException */ private void AddPdfTable(Table t) { // before every table, we flush all lines FlushLines(); PdfTable table = new PdfTable(t, IndentLeft, IndentRight, IndentTop - currentHeight); RenderingContext ctx = new RenderingContext(); ctx.pagetop = IndentTop; ctx.oldHeight = currentHeight; ctx.cellGraphics = new PdfContentByte(writer); ctx.rowspanMap = new Hashtable(); ctx.table = table; // initialisation of parameters PdfCell cell; // drawing the table ArrayList headercells = table.HeaderCells; ArrayList cells = table.Cells; ArrayList rows = ExtractRows(cells, ctx); bool isContinue = false; while (cells.Count != 0) { // initialisation of some extra parameters; ctx.lostTableBottom = 0; // loop over the cells bool cellsShown = false; // draw the cells (line by line) ListIterator iterator = new ListIterator(rows); bool atLeastOneFits = false; while (iterator.HasNext()) { ArrayList row = (ArrayList) iterator.Next(); AnalyzeRow(rows, ctx); RenderCells(ctx, row, table.HasToFitPageCells() & atLeastOneFits); if (!MayBeRemoved(row)) { break; } ConsumeRowspan(row, ctx); iterator.Remove(); atLeastOneFits = true; } // compose cells array list for subsequent code cells.Clear(); Hashtable opt = new Hashtable(); foreach (ArrayList row in rows) { foreach (PdfCell cellp in row) { if (!opt.ContainsKey(cellp)) { cells.Add(cellp); opt[cellp] = null; } } } // we paint the graphics of the table after looping through all the cells Rectangle tablerec = new Rectangle(table); tablerec.Border = table.Border; tablerec.BorderWidth = table.BorderWidth; tablerec.BorderColor = table.BorderColor; tablerec.BackgroundColor = table.BackgroundColor; PdfContentByte under = writer.DirectContentUnder; under.Rectangle(tablerec.GetRectangle(Top, IndentBottom)); under.Add(ctx.cellGraphics); // bugfix by Gerald Fehringer: now again add the border for the table // since it might have been covered by cell backgrounds tablerec.BackgroundColor = null; tablerec = tablerec.GetRectangle(Top, IndentBottom); tablerec.Border = table.Border; under.Rectangle(tablerec); // end bugfix ctx.cellGraphics = new PdfContentByte(null); // if the table continues on the next page if (rows.Count != 0) { isContinue = true; graphics.SetLineWidth(table.BorderWidth); if (cellsShown && (table.Border & Rectangle.BOTTOM_BORDER) == Rectangle.BOTTOM_BORDER) { // Draw the bottom line // the color is set to the color of the element Color tColor = table.BorderColor; if (tColor != null) { graphics.SetColorStroke(tColor); } graphics.MoveTo(table.Left, Math.Max(table.Bottom, IndentBottom)); graphics.LineTo(table.Right, Math.Max(table.Bottom, IndentBottom)); graphics.Stroke(); if (tColor != null) { graphics.ResetRGBColorStroke(); } } // old page pageEmpty = false; float difference = ctx.lostTableBottom; // new page NewPage(); // G.F.: if something added in page event i.e. currentHeight > 0 float heightCorrection = 0; bool somethingAdded = false; if (currentHeight > 0) { heightCorrection = 6; currentHeight += heightCorrection; somethingAdded = true; NewLine(); FlushLines(); indentation.indentTop = currentHeight - leading; currentHeight = 0; } else { FlushLines(); } // this part repeats the table headers (if any) int size = headercells.Count; if (size > 0) { // this is the top of the headersection cell = (PdfCell) headercells[0]; float oldTop = cell.GetTop(0); // loop over all the cells of the table header for (int ii = 0; ii < size; ii++) { cell = (PdfCell) headercells[ii]; // calculation of the new cellpositions cell.Top = IndentTop - oldTop + cell.GetTop(0); cell.Bottom = IndentTop - oldTop + cell.GetBottom(0); ctx.pagetop = cell.Bottom; // we paint the borders of the cell ctx.cellGraphics.Rectangle(cell.Rectangle(IndentTop, IndentBottom)); // we write the text of the cell ArrayList images = cell.GetImages(IndentTop, IndentBottom); foreach (Image image in images) { cellsShown = true; graphics.AddImage(image); } lines = cell.GetLines(IndentTop, IndentBottom); float cellTop = cell.GetTop(IndentTop); text.MoveText(0, cellTop-heightCorrection); float cellDisplacement = FlushLines() - cellTop+heightCorrection; text.MoveText(0, cellDisplacement); } currentHeight = IndentTop - ctx.pagetop + table.Cellspacing; text.MoveText(0, ctx.pagetop - IndentTop - currentHeight); } else { if (somethingAdded) { ctx.pagetop = IndentTop; text.MoveText(0, -table.Cellspacing); } } ctx.oldHeight = currentHeight - heightCorrection; // calculating the new positions of the table and the cells size = Math.Min(cells.Count, table.Columns); int i = 0; while (i < size) { cell = (PdfCell) cells[i]; if (cell.GetTop(-table.Cellspacing) > ctx.lostTableBottom) { float newBottom = ctx.pagetop - difference + cell.Bottom; float neededHeight = cell.RemainingHeight; if (newBottom > ctx.pagetop - neededHeight) { difference += newBottom - (ctx.pagetop - neededHeight); } } i++; } size = cells.Count; table.Top = IndentTop; table.Bottom = ctx.pagetop - difference + table.GetBottom(table.Cellspacing); for (i = 0; i < size; i++) { cell = (PdfCell) cells[i]; float newBottom = ctx.pagetop - difference + cell.Bottom; float newTop = ctx.pagetop - difference + cell.GetTop(-table.Cellspacing); if (newTop > IndentTop - currentHeight) { newTop = IndentTop - currentHeight; } cell.Top = newTop ; cell.Bottom = newBottom ; } } } float tableHeight = table.Top - table.Bottom; // bugfix by Adauto Martins when have more than two tables and more than one page // If continuation of table in other page (bug report #1460051) if (isContinue) { currentHeight = tableHeight; text.MoveText(0, -(tableHeight - (ctx.oldHeight * 2))); } else { currentHeight = ctx.oldHeight + tableHeight; text.MoveText(0, -tableHeight); } pageEmpty = false; }